【问题标题】:Excel VBA Macro to loop, copy, paste, offset based on extracted cell valueExcel VBA宏根据提取的单元格值循环、复制、粘贴、偏移
【发布时间】:2021-08-31 23:47:26
【问题描述】:

我一直在努力为同事清理这些 csv 数据。 我将浏览数据通常的样子,然后浏览我已经完成的步骤,然后提出我目前正在努力解决的问题......请耐心等待,因为这是我的第一篇文章(我没有背景在 vba 中,一切都是谷歌自学的)。 所以数据导出是一个 csv,它可以在 excel 中打开,由几列分开。有问题的列是 G 列,它本质上具有相同菜单项(行)的多个数据集 (1 - 219)。

例如:

A   B   C         D E F     G

Chicken Soup            {1;$6.00;59;$9.00;88;$6.00}
Beef Soup               {1;$8.00;59;$12.00;88;$8.00}
Duck Soup               {1;$6.00;59;$6.00;88;$6.00}
Egg Soup                {1;$8.00;59;$9.00;88;$8.00}
Water                   {1;$0.00}
French Onion Soup       {1;$16.00;59;$15.00;88;$12.00}
Chili Soup              {1;$17.00;84;$17.00}

所以在 G 列中,你可以看出,有多个价格,格式为:

{列号;美元价格;列号 $ 价格等 & }

Regex: .[0-9]{1,2},[$][0-9]{1,3}[.][0-9][0-9].|[0-9]{1,2},[$][0-9]{1,3}[.][0-9][0-9]

第一个目标是将列中的数据解析为行中的数据,格式与 csv 一致(因此可以合并并重新提交)。 例如:(假设每个数据集之间有一个分号,最终结果中应该有)

{1;$21.00}      
{1;$16.00}      
{1;$12.00   5;$12.00    8;$12.00}   
{1;$18.00   6;$18.00    8;$18.00}   
{1;$10.00   6;$7.00 9;$12.00    11;$10.00}
{1;$20.00   6;$20.00    8;$20.00}   
{1;$5.49    3;$3.99 10;$4.99    12;$4.99}
{1;$18.99}      
{1;$21.00}      
{1;$21.00}  

为了实现这个目标,我写了一个宏:

  1. 从“Sheet1”复制 G 列并输入到 A1 中的新工作表“Sheet2”
  2. 将所有“;$”替换为“,$”,以帮助单独分隔每个数据集,而不是将其分解为列名,然后在两个不同的列中使用美元符号
  3. “;”上的文本到列宏拆分(并从 B1 开始输入结果,因此我可以将 A1 与所有数据集放在一列中,以备不时之需)——如果您知道如何在此处保留分号,那将很有帮助,因此我不必重新- 将来添加它
  4. 将所有从 b1 到数据集末尾的“,”替换为“;”
  5. 将数据从B1复制到最后一个有数据的单元格(数据不按顺序,第50行可能有219列,然后最后一行只能有150列)并将这些数据粘贴到“rp items”的G列(因此覆盖现有数据并将列向右移动到使用的最后一列。

但是,当我向我的同事展示我所做的事情时,他希望前导数字(列号)对应于列(因为数据从 G 列开始,这将是第 1 列,H 将是 2 等) .因此看起来像这样,这样他就可以通过具有该列号的所有项目来过滤该列:

For example, this photo is how the outcome should look

所以,现在的目标是创建一个宏……

  1. 循环遍历工作表“STEP ONE”中的 B1:B(B 列从 B1 开始,然后是 C1,当该行中的空白时转到下一行)
  2. 当(B1(或下一行)为空白时,什么都不做,结束宏)
  3. 如果 B1(或活动单元格)不为空,则读取单元格值以提取列;复制单元格的内容,粘贴到“STEP TWO”表中与活动单元格相同的行,但从单元格值偏移列号。
  4. 切换回主工作表,转到该行中的下一个单元格 - 如果为空白,转到下一行并重复,直到完成所有数据。

给你一些背景知识,我有超过 25,000 行数据(菜单项)和最长的列(我相信是 219)。到目前为止,我大部分时间都在尝试我在网上找到的一些脚本,但没有一个与我需要的相似,而且我不知道如何编写足够的代码来自己编写脚本。我相信我需要建立一个变量:列名(不确定我是否可以使用我发现的正则表达式代码提取它)然后在偏移量中使用它...... 但是我的范围需要是动态的和循环的…… 如果您能提供帮助,请告诉我 - 我已经坚持了一周!

非常感谢大家的阅读——如果我可以提供更多详细信息,请告诉我。

【问题讨论】:

    标签: excel vba parsing offset


    【解决方案1】:

    例如,您可以这样做:

    Sub Tester()
    
        Dim arr, i As Long, c As Range, v, col, price
        
        For Each c In Range("G2:G4").Cells
            v = Replace(Replace(c.Value, "{", ""), "}", "") 'remove braces
            If Len(c.Value) > 0 Then                        'anything to process?
                arr = Split(v, ";")                         'split on ;
                For i = 0 To UBound(arr) - 1 Step 2         'loop 2 at a time
                    col = CLng(Trim(arr(i)))                'column number
                    price = Trim(arr(i + 1))                'price
                    c.Offset(0, col).Value = col & ";" & price
                Next i
            End If
        Next c
    
    End Sub
    

    【讨论】:

    • 非常感谢您的回复!我非常感谢它,虽然这段代码很棒,但我确实有一个问题......列号也是一个目标(而不是要偏移的单元格数),因此如果数字是 6;单元格 B2 中的 $15(假设 B 列是新工作表中的第 1 列),目标应该是 G2 为 6;$15 (抱歉试图做一个图表,但不知道响应中的堆栈限制格式..)再次感谢您,让我知道是否可以帮助澄清进一步。
    • 要将数据放在其他任何地方,您只需调整行c.Offset(0, col).Value = ...,例如ThisWorkbook.Worksheets("someOtherSheet").Cells(c.Row, col).Value = ...
    • 啊,谢谢,这有助于解决另一个工作表问题......但是,我拥有的数据被解析为同一行中的列,所以如果我只有一个数据,它就可以工作列,例如假设 B 列是 1 列:A 列 2;$2.00 将移至 C 列(第 2 列)2,$2.00,但是,我在 B 列中也有数据 3;$3.00(目标列应该是 D)D (第 3 列)3;$3.30... 假设在新工作表上:b 列是目标第 1 列,c 是目标第 2 列,......等等。
    • 抱歉 - 经过更多测试,当我在新工作表中尝试时,您的代码似乎适用于此 - 再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多