2015-06-01 84 views
0

我一直在解決以下問題一段時間,並且我得到了一個非常基本的版本,可以在沒有錯誤處理的情況下工作。我的目標是讓這個宏從個人宏觀工作簿中運行。從已關閉的工作簿填充正確的標題

我正在從各種來源導入管道分隔的文本文件,並且標題中的格式都不匹配(某些提供程序決定使用整個佈局)。有了這個問題,我創建了一個名爲Reference(又名Map)的Excel工作簿,其中包含傳入文件佈局和標準化/更正列的名稱格式。

對我來說好消息是,文件ID將始終在A列。我每個月需要處理約65個文件,因此我需要儘量減少所有可能的步驟,因此需要關閉參考工作簿。

因此,我在網上環顧四周,將大部分解決方案放在一起,根據位於A3中的ID拉入新的標題。然而,仍然存在一個困境,有時A3上的ID不會存在於參考工作簿上 - 我需要讓vlookup向下移動到下一行,直到結果不等於#N/A或0或空白。

在這一點上,我得到'Do Loop Until'爲第一場比賽找到正確的一行 - 完全無法跟隨它後面的任何代碼。

只要vlookup找到一個包含現有ID的行,然後運行下面的代碼片段來填充剩餘的標頭。下一步的唯一副作用是,由於某種原因,rID偏移+1行,如果最後一行不包含匹配的ID,則撤消'Do Loop'直到'。

'> 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 
+0

旨在爲數字您的任何頭?我發現.txt文件在分隔後經常會有拖尾/前導空格,而這會將它們轉換爲字符串。 – TMH8885

+0

所有標題都是文本 - 清理的目的是爲了能夠減少通過查詢運行的Microsoft Access文件的數量來清理數據。我每個月處理幾百萬個單獨的條目。如果所有文件具有相同的頭文件,那麼導入Access的過程將是一個巨大的緩解。 – ExcelNovice2015

+0

我最終取消了列計數驗證,因爲我可以編輯vlookup並添加更多字段。 – ExcelNovice2015

回答

1

我會盡力幫助一點,因爲你表現出精力來學習。我會給你一些關於整體VBA編碼的有用提示,以及關於你的問題。請儘量記住它們。

  1. 由於您的變量名稱很差,很難讀取您的代碼。在VBA中,單元格和它的值之間存在差異。在你的代碼中你有rng1rng2。我看到當前rng1代表單元格的值,而rng2 - 單元格本身。我不確定你是否故意這樣做,但現在你會理解它。如果你的意思是一個單元本身,那麼命名變量rng2是很好理解的。但是,如果你指的是單元格的價值,那麼命名變量rng1是有誤導性的。這只是爲了能夠更輕鬆地閱讀代碼。由於您將此變量定義爲string,我懷疑您希望它獲得string類型的值。因此,您應該將變量命名爲與其類型相關的內容,即以str...s...開頭的內容,這意味着此變量的類型爲string,例如, strValuesID。最好的方法是使用str,因爲s可能會與single類型混淆(在VBA中也有這樣的數據類型)。您應該將此邏輯應用於您使用的每個變量。 String - str...,long - lng...,integer - int...,double - dbl...,boolean - bln...等等。一種類型是特定類型,您也可以在此處使用它。這是object類型。對象不僅僅是對象,它們被分解爲許多不同的類型,並且在你的代碼中你也使用了對象rangeworkbook。你能說出他們o...obj...,或者它通常最好使用一個更具體的名稱,如rng...(爲範圍)或wb...(爲工作簿)。通常的數據類型的變量可取的值而不Set子句,而對象總是需要Set爲了與一些實際對象關聯,像範圍,工作簿時,片材等。在您的代碼,我們看到wb2變量這是一個string。現在你知道,那不好。 因此,在這種情況下,你應該,如果你希望它是string而不是range,學會始終使用此命名約定重命名rng1。同樣適用於wb2

  2. 在所有sub s之前,始終使用Option Explicit作爲代碼模塊中的最頂層行。這只是防止錯別字。這實際上是一條不可或缺的路線。我總是使用它,每個人都應該。這樣做後,我看到你的代碼不會運行,因爲cell變量沒有定義。使用Dim cell As Range,因爲單元格實際上是range類型的對象。在這種情況下,Set被省略,因爲For Each ... In ... Next循環會爲您執行該操作。

現在你的實際問題。

  1. 您會發現Worksheet.UsedRange對確定列數有用。這表示從A1到最後一個使用的單元格(這實際上是最後使用的列和最後一個使用的行的交叉點)的工作表中的區域。假設你的數據從A列跨越,當它結束還有沒有更多的數據是正確的不屬於任何列,您可以使用ActiveSheet.UsedRange.Columns.Count讓你UsedRange,希望在您的工作表中的列數。

  2. 我提到UsedRange第一,因爲我想讓你得到熟悉它。我們將用它來解決vlookup的問題。因此,在vlookup之前我建議的第一步是找到帶有您的ID的單元。我們應該首先使用dim個變量,例如rng3

Dim rng3 As Range

那麼我的建議是找到ID通過細胞在A列循環,開​​始的A3,但不循環,直到柱末端的小區,因爲有1米行,但直到我們達到最後的實際使用排:

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. 

現在,我們有你自己的ID爲單元,我們可以把查找在:

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 

我希望這裏沒有錯別字,因爲我沒有測試過它。但是,我仔細檢查了代碼,它看起來不錯。

+0

感謝ZygD的詳細概述,具有良好特定名稱的屬性使得完全有意義;特別是如果共享代碼。 – ExcelNovice2015

0

我得到它一起工作:

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 
相關問題