2015-10-28 24 views
0

我已經創建了從其他(關閉)excel文件導入數據的主文件。有十個文件需要從中導入數據。我在UserForm中創建了一個代碼,這樣我的老闆可以選擇在哪裏導入(sheet = wariant)文件。它沒有完成,因爲我需要添加選項按鈕(用於選擇要導入的文件),但主核心看起來像在下面。GetValue + loop =它可以更快嗎?

但是有一個問題,在我們公司我們有一箇中等級別的筆記本電腦,所以在每個文件(wariant)5-7分鐘執行的代碼(在下面)。我需要它儘可能快地運行。你能用它做點什麼嗎?

Private Sub CommandButton1_Click() 

StartTime = Timer 

Dim p As String 
Dim f As String 
Dim s As String 
Dim a As String 
Dim r As Long 
Dim c As Long 
Dim Warinat As String 

    If UserForm1.War1 = True Then Wariant = "Wariant 1" 
    If UserForm1.War2 = True Then Wariant = "Wariant 2" 
    If UserForm1.War3 = True Then Wariant = "Wariant 3" 
    If UserForm1.War4 = True Then Wariant = "Wariant 4" 

    p = ThisWorkbook.path 
    f = "files.xlsx" 
    s = "Sheet1" 

    Application.ScreenUpdating = False 

    For r = 7 To 137 
    For c = 2 To 96 
    a = Cells(r, c).Address 
    If IsNumeric(Cells(r, c)) = True And ThisWorkbook.Sheets(Wariant).Cells(r, c) <> "" _ 
    Then ThisWorkbook.Sheets(Wariant).Cells(r, c) = _ 
    ThisWorkbook.Sheets(Wariant).Cells(r, c).Value + GetValue(p, f, s, a) 
    Else 
    ThisWorkbook.Sheets(Wariant).Cells(r, c) = GetValue(p, f, s, a) 
    End If 
    Next c 
    Next r 

EndTime = Timer 
MsgBox Format(EndTime - StartTime, ssss) 

Unload Me 

End Sub 

Private Function GetValue(path, file, sheet, ref) 

    Dim arg As String 

    If Right(path, 1) <> "\" Then path = path & "\" 
    If Dir(path & file) = "" Then 
     GetValue = "Files is missing" 
     Exit Function 
    End If 

    arg = "'" & path & "[" & file & "]" & sheet & "'!" & _ 
Range(ref).Range("A1").Address(, , xlR1C1) 

GetValue = ExecuteExcel4Macro(arg) 

End Function 

Private Sub CommandButton2_Click() 

Unload Me 

End Sub 

Private Sub UserForm_Click() 

End Sub 
+0

'Dim Warinat As String' has a typo。使用Option Explicit作爲模塊的第一行。 – user1016274

回答

1

您的ExecuteExcel4Macro調用可能會減慢進程速度,因爲它會打開相同的工作簿12,445次。你正在處理兩個二維數組;一個在你的Wariant表單中,另一個在你導入的工作簿中。嘗試這樣的事情。

Dim var1 As Variant 
Dim var2 As Variant 
Dim wbImport As Workbook 

'Set var1 as your range value 
var1 = ThisWorkbook.Sheets(Wariant).Range("B7:CR137").Value 

'Open the Import workbook, set the value, then close it. 
Set wbImport = Application.Workbooks.Open(p & f) 
var2 = wbImport.Sheets("Sheet1").Range("B7:CR137").Value 
wbImport.Close 

'Now loop through the variant arrays - much faster 
For r = 1 To 131 
    For c = 1 To 95 

     If IsNumeric(var1(r, c)) And var1(r, c) <> "" Then 
      var1(r, c) = _ 
      var1(r, c) + var2(r, c) 
     Else 
      var1(r, c) = var2(r, c) 
     End If 
    Next c 
Next r 

'Finally, copy the variant array back into the workbook. 
ThisWorkbook.Sheets(Wariant).Range("B7:CR137").Value = var1 
+0

我認爲這是一個明確的答案:將範圍讀入一個數組中,單個「hit」總是比單個單元格的多次讀取更快:這樣可以讓您也可以把VBA中的任何事情都視爲零時間......除非它真的很慢,比如打開文件或者從封閉文件中讀取。或者,正如斯塔德姆所指出的,數千次閱讀相同的工作簿。打開文件並保持打開狀態,也許可以通過一種方式將數據抓取到一個數組中,也可以在一次「碰撞」中進行! –

+0

謝謝,它真的在2秒鐘內工作:)我是VBA的初學者,所以我將從您的代碼中學到很多東西! – BenNowak

0

不是不知道你與ExecuteExcel4Macro函數調用什麼,因爲所謂的宏可以是任何東西,並且很可能是原因,你的代碼excecutes慢慢

GetValue = ExecuteExcel4Macro(arg) 
+0

我以爲同樣的事情,但我猜ExecuteExcel4Macro實際上是一個標準的VBA函數:https://msdn.microsoft.com/en-us/library/office/ff193589.aspx – Stadem

+1

是的,啓動自定義宏的標準函數 – tsolina

+0

在@ BenNowak的情況下,這個說法不叫宏;它調用一個單元格引用值。請參閱http://stackoverflow.com/a/27527560/5103770 – Stadem

1

它可能會,如果你打開每一個跑得更快工作簿,而不是從封閉的工作簿讀取單元格。

0

要做到這一點,而無需打開工作簿,您可以將此代碼粘貼到一個新的模塊:

Dim v As Variant 

Function GetValues(p As String, f As String, s As String, a As String) 
v = Empty 
Application.ExecuteExcel4Macro "'" & ThisWorkbook.Name & "'!SetV('" & p & "\[" & f & "]" & s & "'!" & a & ")" 
GetValues = v 
End Function 

Public Function SetV(Value) 
v = Value 
End Function 

然後你可以檢索這樣的單個呼叫從關閉的工作簿中的所有值:

GetValues(ThisWorkbook.path,"files.xlsx","Sheet1","r7c2:r137c96") 
相關問題