从已closures的工作簿填充正确的标题

我一直在解决这个问题一段时间,我有一个非常基本的版本工作,没有error handling。 我的目标是从macros观个人工作簿中运行这个macros。

我正在导入来自各种来源的pipe道分隔文本文件,而且标题中的格式都不匹配(有些提供者决定使用整个布局)。 有了这个问题,我创build了一个名为Reference(也称为Map)的Excel工作簿,其中包含传入的文件布局和标准化/更正的列名称格式。

对我来说好消息是,文件ID总是在A列。我有大约65个需要每个月处理的文件,所以我需要最小化所有可能的步骤,因此需要closures参考工作簿。

有了这个,我在网上环顾四周,将大部分解决scheme放在一起,根据位于A3中的ID拉入新的标题。 但仍然存在一个困境,有时A3上的ID将不会存在于参考工作簿上 – 我需要让vlookup下移到下一行,直到结果不等于#N / A或0或空白。

在这一点上,我得到了'Do Loop Until'来find第一个匹配的正确的行 – 完全无法使用任何后面的代码。

一旦vlookupfind一个具有现有ID的行,然后运行下面的代码片段填充剩余的标题。 下一步的唯一副作用是,由于某种原因,rID偏移+1行,如果最后一行不包含匹配的ID,则取消“直到执行循环”。

'> Populate remining headers For Each cell In rng1 cell.Value = ("=VLOOKUP(" & cID & rID & "," & map & "," & i & ",FALSE)") i = i + 1 Next 

这是我迄今为止:

 Sub DAc_lookup_headers() Dim wb1 As Workbook 'Current text/file Dim map As String 'reference Map Dim cID As String 'wb1 look up column A Dim rID As String 'wb1 starting row number Dim rng1 As Range 'wb1 Collection header range Dim i As Long 'Index number per cell in range Set wb1 = ActiveWorkbook Set rng1 = wb1.ActiveSheet.[A1:G1] map = ("'C:\Users\x165422\Desktop\New folder\[Reference.xlsx]Ref'!$A$1:$I$13") rID = 3 'Row where ID is - will increment + 1 if not found cID = "A" 'Column where ID is i = 3 'Starting vlookup Index number - to increment per cell in range '>Look for ID until value is found Do wb1.ActiveSheet.[a1].Value = ("=VLOOKUP(" & cID & rID & "," & map & "," & i & ",FALSE)") rID = rID + 1 Loop Until wb1.ActiveSheet.[a1].Text <> "#N/A" Or "0" '> Populate remining headers For Each cell In rng1 cell.Value = ("=VLOOKUP(" & cID & rID & "," & map & "," & i & ",FALSE)") i = i + 1 Next '> Convert to values With rng1 .Value = .Value End With End Sub 

我会尽力帮助一下,因为你performance出努力去学习。 我会给你一些关于整体VBA编码的有用提示,以及你的问题。 请尽量记住它们。

  1. 读取代码很困难,因为你的variables命名不当。 在VBA中,单元格和它的值是有区别的。 在你的代码中你有rng1rng2 。 我发现目前rng1代表单元格的值,而rng2 – 单元格本身。 我不确定你是否故意这样做,但现在你会明白这一点。 如果你的意思是一个单元格本身,那么命名variablesrng2是很好理解的。 但是,如果你指的是单元格的价值,那么命名variablesrng1是有误导性的。 这只是为了能够更容易地阅读代码。 由于您将此variables定义为string ,我怀疑您希望它接收stringtypes的值。 所以,你应该把你的variables命名为与它的types有关的东西,例如以str...s...开头的东西,这意味着这个variables是stringtypes的,例如strValuesID 。 最好的方法是使用str ,因为s可能与singletypes混淆(在VBA中也有这样的数据types)。 你应该把这个逻辑应用到你使用的每个variables上。 String – str... ,long – lng... ,integer – int... ,double – dbl... ,boolean – bln...等等。一种types是特定的,您也可以在这里使用它。 这是objecttypes。 对象不仅仅是对象,它们被分解成许多不同的types,在你的代码中你也可以使用rangeworkbook对象。 您可以将它们命名为o...或者obj... ,或者通常最好使用更具体的名称,例如rng... (用于范围)或wb... (用于工作簿)。 通常的数据typesvariables取值没有Set子句,而对象总是需要Set来关联一些实际的对象,比如范围,工作簿,工作表等。在你的代码中,我们看到wb2variables是一个string 。 现在你知道,那不好。 所以,在这种情况下,如果你期望它是string而不是range并且总是使用这个命名约定,你应该重命名rng1 。 和wb2

  2. 总是使用Option Explicit作为代码模块中的最上面一行,在所有sub节点之前。 这只是防止错别字。 而这实际上是一条不可或缺的路线。 我总是使用它,每个人都应该。 这样做后,我看到你的代码将不会运行,因为cellvariables没有定义。 使用Dim cell As Range ,因为单元格实际上是rangetypes的对象。 在这种情况下Set被省略,因为For Each ... In ... Next循环为你做。

现在你的实际问题。

  1. 你会发现Worksheet.UsedRange用于确定列数。 这表示从A1到最后一个使用的单元格(这实际上是最后使用的列和最后一个使用的行的交叉点)的工作表中的区域。 鉴于你的数据跨越列A,当它结束时,没有更多的数据不属于任何列的权利,你可以使用ActiveSheet.UsedRange.Columns.Count来获得你UsedRange的列数,希望在你的片。

  2. 我首先提到了UsedRange ,因为我想让你熟悉它。 我们将用它来解决vlookup问题。 所以在vlookup之前我build议的第一步是find带有你的ID的单元。 我们应该先dim我们将要使用的variables,例如rng3

 昏暗rng3作为范围 

然后我的build议是find单元格ID循环通过A列中的单元格,开始A3,但不循环直到列的末尾,因为有1m行,但直到我们到达最后一个实际使用的行:

 For Each cell In wb1.ActiveSheet.Range("A3:A" & wb1.ActiveSheet.UsedRange.Rows.Count) If cell <> "" Then Set rng3 = cell Exit For 'we found the value, no need to continue looping, so we exit the For loop End If Next 'there is no need to write "cell" after "Next", because VBA knows which loop it is in. 

现在,我们有你的身份证的单元格,我们可以在以下位置查找:

 i = 2 'Starting vlookup Index number per cell in range For Each cell in rng2 cell.Value = "=VLOOKUP(" & rng3.Address & "," & wb2 & "," & i & ",FALSE)" 'again, wb2 is not a nice name for String variable i = i + 1 Next 

我希望这里没有错别字,因为我没有testing过。 但是,我已经仔细检查了代码,它看起来不错。

我得到它与工作:

 Sub DAc_lookup_headers() Dim wb1 As Workbook 'Current text/file Dim map As String 'reference Map Dim cID As String 'wb1 look up column A Dim rID As String 'wb1 starting row number Dim rng1 As Range 'wb1 Collection header range Dim i As Long 'Index number per cell in range Set wb1 = ActiveWorkbook Set rng1 = wb1.ActiveSheet.[A1:G1] map = ("'C:\Users\x165422\Desktop\New folder\[Reference.xlsx]Ref'!$A$1:$I$13") rID = 2 'Row where ID is - will increment + 1 if not found cID = "A" 'Column where ID is i = 3 'Starting vlookup Index number - to increment per cell in range '>Look for ID until value is found Do rID = rID + 1 wb1.ActiveSheet.[a1].Value = ("=VLOOKUP(" & cID & rID & "," & map & "," & i & ",FALSE)") Loop Until wb1.ActiveSheet.[a1].Text <> "#N/A" Or "0" '> Populate remining headers For Each cell In rng1 cell.Value = ("=VLOOKUP(" & cID & rID & "," & map & "," & i & ",FALSE)") i = i + 1 Next '> Convert to values With rng1 .Value = .Value End With End Sub