【问题标题】:Need to loop through & modify cells in an Excel sheet... Where do I start?需要遍历和修改 Excel 工作表中的单元格...我从哪里开始?
【发布时间】:2017-03-29 13:26:41
【问题描述】:

我在做什么

我需要修改一个文件(从 salesforce 导出),其中行具有唯一 ID、名称和具有此表中另一行的唯一 ID 的列,将其标识为该项目的“子项”。

  1. ID(columnA
  2. 名称(列 B
  3. 父 ID(columnC

未受影响数据的图像:

我需要完成什么

我的目标是遍历整个电子表格(55,000 行)并将 ParentID 更改为父名称列中的值。

我的伪代码解决方案

foreach row starting from the top {
    varA = [current row number for this loop];
    varX = [value in varA:columnC];
    if (varX == [regex value]) {
        foreach row starting from the top {
            varB = [current row number for this loop];
            if ([value in varB:columnA] == varX) {              
                foreach row starting from the top {
                    varC = [current row number for this loop];
                    if (varC:columnC = varB:columnA) {
                        [varC:columnC] = [varB:columnB];
                    }
                }
                break second foreach loop;
            }
        }
    }
}

手动修复后的数据图:

到目前为止我所做的研究

我正在使用 excel,我找到了讨论如何创建新宏的资源,其中一些甚至有示例,但我不确定这是否是合适的地方。我还有一个朋友建议使用 Pandas 修改文件会更好,但我也不熟悉。

我的问题:

我从哪里开始? ...编写脚本来修改所有这些的正确工具是什么?

另外,如果可能的话,您能否推荐一个资源供我在使用合适的工具完成这项工作时作为参考?

【问题讨论】:

  • 所以你在第一个有001, Ted, 002,在第二个有002, Bob, 099,你想把第一个改成001, Ted, Bob ...?如果找不到匹配项怎么办?
  • 你能贴一张你预期结果的小图吗?和一些样本数据,你可以伪造它我们不需要看实际值。如果我理解正确的话,这似乎很容易用公式来实现。
  • 是否考虑将父母的姓名复制过来以替换 ID?还是我误解了你的需求?如果复制/粘贴可以解决并且没有很多空白单元格,只需单击名称行中的第一个,按住 CTRL+Shift 并单击向下箭头。将其复制并粘贴到之前的 ID 上
  • 感谢您与我讨论这个问题 - 我已根据 Miguel 的要求添加了图片。 Chris,据我估计,手动为每个 ParentID 执行查找+替换需要几天时间才能完成。

标签: vba excel


【解决方案1】:

改变这个,

.. 使用此代码,

Option Explicit

Sub wqweqrteq()
    Dim d As Long, dict As Object, vals As Variant

    Set dict = CreateObject("Scripting.Dictionary")

    With Worksheets("salesforce")
        With .Range(.Cells(2, "A"), .Cells(.Rows.Count, "C").End(xlUp))
            vals = .Value2
        End With

        For d = LBound(vals, 1) To UBound(vals, 1)
            dict.Item(vals(d, 1)) = vals(d, 2)
        Next d

        For d = LBound(vals, 1) To UBound(vals, 1)
            If dict.exists(vals(d, 3)) Then
                vals(d, 3) = dict.Item(vals(d, 3))
            End If
        Next d

        With .Range(.Cells(2, "A"), .Cells(.Rows.Count, "C").End(xlUp))
            .Value = vals
        End With
    End With

End Sub

.. 进入这个。

【讨论】:

  • 我打开工作表,将名称更改为“salesforce”,列名与此处匹配,然后从开发人员工具中打开“Visual Basic”,选择“salesforce”工作表,然后在右侧的白色字段我输入了您建议的代码并单击运行。它给出了错误代码 429。知道为什么吗?
  • 好吧,既然您认为指定哪一行实际引发错误并不重要,我冒昧地猜测您无法创建脚本字典对象。如果是这种情况,请修复您的 Office 安装。
  • 由于我最初的要求是关于使用什么工具的指导,我并不羞于说我在粘贴上面给出的代码时仍然不确定我是否在正确的位置。因此,我的冗长回复询问了您的解决方案为何不起作用的想法。弹出的错误不包含行号,所以我真的没有决定什么。
  • 通常,您会将其放置在标准模块(Inert、Module 或 Alt+I、M)中,而不是工作表的代码表中,但如果您确实将其放置在工作表的代码表中,它应该运行为那个工作表。
【解决方案2】:

以下 For 循环 可以解决您的问题:

Sub UpdateID()

Dim lastrow As Long
Dim x As Long, y As Long, z As Long
Dim ParentName As String

lastrow = Cells(Rows.Count, "A").End(xlUp).Row

For x = 2 To lastrow
    If Left(Cells(x, 3), 2) = 0 Then
        For y = 2 To lastrow
            If Cells(x, 3).Value = Cells(y, 1).Value Then
            ParentName = Cells(y, 2).Value
            Exit For
            End If
        Next y
    End If

    For z = 2 To lastrow
        If Cells(z, 3).Value <> "" And Cells(x, 3).Value = Cells(z, 3).Value Then
        Cells(z, 3).Value = ParentName
        End If
    Next z
Next x

End Sub

【讨论】:

  • 嗨皮特,感谢您在这里帮助我。我把这段代码放到 Visual Basic 编辑器的相应工作表中,但运行代码后 Excel 已经挂了十多分钟。这是正常的,还是我输入错误的地方?
  • @EddieKnight - 50K 行数据是正常的。加快速度的方法是使用字典和变体数组。
  • 是的,对于大型数据集,循环总是需要很长时间。
  • 感谢各位的帮助,但即使在缩小文件大小的情况下,它也会旋转大约 45 分钟......我想我对从哪里开始有一个根本的误解。我将开始寻找另一种解决方案。还是谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多