2017-01-13 48 views
-1

我有一個通過多個文件(> 100)的代碼。它打開文件,並將該信息放入數組中。在每個新文件中,行中的項目數可能會發生變化(增加或減少)。我使用第二個數組來說明這一點。查看數組中的列並複製數據

列標題也會在文件中更改(不同列位置中的標題)。我的問題是我正在嘗試通過第一行(標題)上的列,看看它們是否在該文件數組中,如果它們是,將該信息複製到輸出文件(如果它們不是,請將「 - 「)。

當前的代碼:

Sub Price() 
Dim w As Workbook 
Dim w2 As Workbook 
Dim start1 As Long, end1 As Long, i As Long, lRow As Long, lColumn As Long, t As Long, k As Long, position As Long, g As Long, p As Long, u As Long 
Dim WBArray() As Variant 
Dim r As Range 
Dim Header(): ReDim Header(0) 
Dim IS3(): ReDim IS3(0) 'this fix the subscript out of range error 
Dim ws As Worksheet 

Dim MyFolder As String 
Dim MyFile As String 

Set w = ThisWorkbook 

'clean all worksheets in the main file (except FILES) 
For Each ws In w.Worksheets 
    If ws.Name <> "FILES" Then 
     ws.UsedRange.ClearContents 
    End If 
Next ws 

'Optimize Macro Speed Start 
Application.ScreenUpdating = False 
Application.EnableEvents = False 
Application.Calculation = xlCalculationManual 

'opens the first workbook file 
For i = 2 To ThisWorkbook.Sheets("FILES").Cells(1, 2).Value 

    Workbooks.Open Filename:=ThisWorkbook.path & "\" &  ThisWorkbook.Sheets("FILES").Cells(i, 1).Value 

    Set w2 = ActiveWorkbook 
    ActiveSheet.Range("A:A").Select 

    'text to columns 
    Selection.TextToColumns destination:=Range("A1"), DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _ 
     Semicolon:=True, Comma:=True, Space:=False, Other:=False, FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7 _ 
     , 1), Array(8, 1), Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1), Array(13, 1), Array(14, 1), Array(15, 1), Array(16, 1), Array(17 _ 
     , 1), Array(18, 1), Array(19, 1), Array(20, 1), Array(21, 1), Array(22, 1), Array(23, 1), Array(24, 1), Array(25, 1), Array(26, 1), Array(27 _ 
     , 1), Array(28, 1), Array(29, 1), Array(30, 1), Array(31, 1), Array(32, 1)), TrailingMinusNumbers:=True 




'create the array based on whanted data 
With ActiveSheet 
Set r = .Columns(1).Find(what:="ISIN", After:=.Cells(.Rows.count, 1), lookat:=xlWhole, _ 
         SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) 
If Not r Is Nothing Then 
    start1 = r.Row 
    end1 = .Range("B" & Rows.count).End(xlUp).Row 
    WBArray = .Range(Cells(start1, 1), Cells(end1, 29)).Value 
End If 
End With 


'loop to match information in two arrays 


    'option 1 *************************************** 

      For lColumn = 2 To UBound(WBArray) 
       If IsInArray((WBArray(1, lColumn)), Header) <> -1 Then 
        p = IsInArray((WBArray(1, lColumn)), Header) 
        'p is position when already in array 

       Else 
        ReDim Preserve Header(LBound(Header) To UBound(Header) + 1) 
        Header(UBound(Header)) = WBArray(1, lColumn) 

        u = UBound(Header) 
        'u is position when not in array, redim to end 
       End If 
      Next lColumn 



       For lRow = 2 To UBound(WBArray) 
         For lColumn = 2 To UBound(WBArray) 
         If IsInArray((WBArray(lRow, 1)), IS3) <> -1 Then 
          t = IsInArray((WBArray(lRow, 1)), IS3) 



      If lColumn.Name = "Cpn" Then 
       w.Sheets("Cpn").Cells(t, i + 3).Value = WBArray(lRow, lColumn) 
      Else 
       'w.Sheets("Cpn").Cells(t, i + 3).Value = "--" 
       Resume Next 
      End if  

      w.Sheets("M").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("W t-1").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("P").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("A").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("PC").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("AM").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("AM t-1").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("Pe t-1").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("F").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("F t-1").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("A t-1").Cells(t, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("S").Cells(t, i + 3) = WBArray(lRow, lColumn) 

     Else 

'add it to the end of IS3Array 



        ReDim Preserve IS3(LBound(IS3) To UBound(IS3) + 1) 
        IS3(UBound(IS3)) = WBArray(lRow, 1) 

        k = UBound(IS3) 



      w.Sheets("C").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("M").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("W t-1").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("P").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("A").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("PC").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("AM").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("AM t-1").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("P t-1").Cells(k + 1, i + 3) = WBArray(lRow, 17) 
      w.Sheets("F").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("F t-1").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 
      w.Sheets("A t-1").Cells(k + 1, i + 3) = WBArray(lRow, 18) 
      w.Sheets("S").Cells(k + 1, i + 3) = WBArray(lRow, lColumn) 

     End If 
     Next lColumn 
    Next lRow 







'copy the file date from each source workbook to output workbook 
'if the control sheet name (FILES) is changed, please change it in this loop 
     For Each ws In w.Worksheets 
      If ws.Name <> "FILES" Then 
       ws.Cells(1, i + 3) = w2.Worksheets(1).Cells(1, 2) 
      End If 
     Next ws 

'Close file And Save 
    w2.Close True 

Next i 

'paste the is3 array to all worksheets 
    g = UBound(IS3) 

For Each ws In w.Worksheets 

    If ws.Name <> "FILES" Then 
    ws.Range("A1:A" & g).Value = Application.WorksheetFunction.Transpose(IS3) 
    End If 

Next ws 

'Optimize Macro Speed 
Application.ScreenUpdating = True 
Application.EnableEvents = True 
Application.Calculation = xlCalculationAutomatic 



End Function 

Public Function IsInArray(stringToBeFound As String, Arr As Variant) As Long 
Dim position As Long 
'default return value if value not found in array 
IsInArray = -1 
If IsArrayEmpty(Arr) Then Exit Function 

For position = LBound(Arr) To UBound(Arr) 'subscript out of range 
    If Arr(position) = stringToBeFound Then 
     IsInArray = position + 1 
     Exit For 
    End If 
Next 

End Function 

Public Function IsArrayEmpty(Arr As Variant) As Boolean 
Dim LB As Long 
Dim UB As Long 

Err.Clear 
On Error Resume Next 
If IsArray(Arr) = False Then 
    IsArrayEmpty = True 
End If 

' Attempt to get the UBound of the array. If the array is unallocated, an error will occur. 
UB = UBound(Arr, 1) 
If (Err.Number <> 0) Then 
    IsArrayEmpty = True 
Else 

Err.Clear 
LB = LBound(Arr) 
    If LB > UB Then 
     IsArrayEmpty = True 
    Else 
     IsArrayEmpty = False 
    End If 
End If 

End Function 

任何想法?

+0

感謝您的回答。顯然,解決這個問題的最好方法是在粘貼循環之前聲明變量。這樣它運行時不會過度迭代。我粘貼了這部分代碼作爲答案。 – DGMS89

回答

0

經過一番研究,我發現最好的方法是在不需要遍歷每個文件中每行的所有列的情況下完成此操作,而無需創建任何標題數組,而是需要聲明我想要的變量,使用IsInArray函數將每個列分配給一列。之後,我將IsInArray函數的結果分配給一個變量,並將其用於粘貼到我的輸出文件。 已更改的部分代碼:

C = IsInArray2("C", WBArray) 
M = IsInArray2("M", WBArray) 
W0 = IsInArray2("W t-1", WBArray) 
P = IsInArray2("P", WBArray) 
Ac= IsInArray2("Ac, WBArray) 
PC = IsInArray2("PC", WBArray) 
AM = IsInArray2("AM", WBArray) 
AM = IsInArray2("AM t-1", WBArray) 
P = IsInArray2("Pt-1", WBArray) 
F = IsInArray2("F", WBArray) 
F0 = IsInArray2("F t-1", WBArray) 
A0 = IsInArray2("Act-1", WBArray) 
S = IsInArray2("S", WBArray) 




'loop to match information in two arrays 

     For lRow = 2 To UBound(WBArray) 
       If IsInArray((WBArray(lRow, 1)), IS3) <> -1 Then 
        t = IsInArray((WBArray(lRow, 1)), IS3) 

         If C <> -1 Then w.Sheets("C").Cells(t, i + 3) =  WBArray(lRow, C) Else: w.Sheets("C").Cells(t, i + 3) = "--" 
         If M <> -1 Then w.Sheets("M").Cells(t, i + 3) = WBArray(lRow, M) Else: w.Sheets("M").Cells(t, i + 3) = "--" 
         If W0 <> -1 Then w.Sheets("W t-1").Cells(t, i + 3) = WBArray(lRow, W0) Else: w.Sheets("W t-1").Cells(t, i + 3) = "--" 
         If P <> -1 Then w.Sheets("P").Cells(t, i + 3) = WBArray(lRow, P) Else: w.Sheets("P").Cells(t, i + 3) = "--" 
         If A <> -1 Then w.Sheets("A").Cells(t, i + 3) = WBArray(lRow, A) Else: w.Sheets("A").Cells(t, i + 3) = "--" 
         If PC <> -1 Then w.Sheets("PC").Cells(t, i + 3) = WBArray(lRow, PC) Else: w.Sheets("PC").Cells(t, i + 3) = "--" 
         If AM <> -1 Then w.Sheets("AM").Cells(t, i + 3) = WBArray(lRow, AM) Else: w.Sheets("AM").Cells(t, i + 3) = "--" 
         If AM0 <> -1 Then w.Sheets("AM t-1").Cells(t, i + 3) = WBArray(lRow, AM0) Else: w.Sheets("AM t-1").Cells(t, i + 3) = "--" 
         If P0 <> -1 Then w.Sheets("P t-1").Cells(t, i + 3) = WBArray(lRow, P0) Else: w.Sheets("P t-1").Cells(t, i + 3) = "--" 
         If F <> -1 Then w.Sheets("F").Cells(t, i + 3) = WBArray(lRow, F) Else: w.Sheets("F").Cells(t, i + 3) = "--" 
         If F0 <> -1 Then w.Sheets("F t-1").Cells(t, i + 3) = WBArray(lRow, F0) Else: w.Sheets("F t-1").Cells(t, i + 3) = "--" 
         If A0 <> -1 Then w.Sheets("A t-1").Cells(t, i + 3) = WBArray(lRow, A0) Else: w.Sheets("A t-1").Cells(t, i + 3) = "--" 
         If S<> -1 Then w.Sheets("S").Cells(t, i + 3) = WBArray(lRow, S) Else: w.Sheets("S").Cells(t, i + 3) = "--" 

的最後一件事是,我創建了一個第二IsInArray功能,下一個步驟是公正的立場,而不是定位+ 1