У меня слово макрос, который scolls через лист Excel, Ускорение взаимодействия между первенствую слово
Как видно он имеет несколько рядов (112), где существует только одна строка, которая должна быть выполнена действие на, тот, у кого есть информация в столбце WP, и информация отсутствует в столбце LS.
Так что в основном мой код - это использовать информацию в этой строке и помещать ее в пользовательские переменные в файл слова шаблона, а затем сохранять текстовый файл с именем LSXXXX (это имя позже записывается в excel). Файл LS XXXX можно увидеть ниже:
Кроме того, некоторые из информации, необходимой для шаблона происходит от другого слова файла (docOut) пользовательских свойств это можно было видно ниже, а:
Код работает, но его чрезвычайно медленно. Я добавил код, чтобы проверить, открыт ли excel другими пользователями, для параметра screenupdating установлено значение false.
Любая идея, как я могу ускорить мой код? Если я использую ссылку на библиотеку excel, это означает, что каждый пользователь, который использует мою библиотеку, должен добавить ссылку на нее сам по себе, и, следовательно, раннее связывание не является действительно практичным.
Ниже фрагменты из моего кода:
Dim i As Integer
Dim oXLApp As Object
Set oXLApp = CreateObject("Excel.Application")
Dim xlapp As Object
'~~> Hide Excel
oXLApp.Visible = False
Dim temp As Variant
'Dictionary with all types
Set temp = getTypes(Settings.userNameFile)
projectnumber = GUI.ComboBoxProjectnumberLogScheme.Value
initGUI.closeGUI
dokut = FileHandling.getDocOutName(projectnumber)
On Error Resume Next
If Not FileHandling.openDocument(dokut) Then
MSG = MsgBox("Doc out does not exist, create it?", vbYesNo, "Creater")
'ask if the user really knows what he is doing...
If MSG = vbYes Then
If Not FileHandling.createDocument(projectnumber) Then
MsgBox "Failed to create document, sorry mate"
GoTo Terminate:
End If
Else
GoTo Terminate:
End If
End If
tittel = Documents(dokut).CustomDocumentProperties("ProsjektTittel")
If tittel = "" Then
' Promt user to input title
tittel = InputBox("Type the project title")
'ask if the user really knows what he is doing...
If tittel = "" Then
GoTo Terminate:
Else
Call createCustomDocumentProperty(dokut, "ProsjektTittel", tittel, msoPropertyTypeString)
End If
End If
subject = "Logg skjema"
company = Documents(dokut).CustomDocumentProperties("_Company")
myKeywords = Documents(dokut).CustomDocumentProperties("_Keywords")
avsender = temp(Environ$("Username"))
ceo = Documents(dokut).CustomDocumentProperties("CEO")
customer = Documents(dokut).CustomDocumentProperties("Customer")
If customer = "" Or customer = "Customer" Then
' Promt user to input title
customer = InputBox("Type the name of the customer")
'ask if the user really knows what he is doing...
If customer = "" Then
GoTo Terminate:
Else
Call createCustomDocumentProperty(dokut, "Customer", customer, msoPropertyTypeString)
End If
End If
myFileName = Settings.projectFolder & projectnumber & "\" & Settings.partsList
If Dir(myFileName) = "" Then
MsgBox "The parts list does not exist, manually copy it over please or rename it to : " & vbNewLine & myFileName
Exit Sub
End If
Dim Ret
Ret = LogScheme.IsWorkBookOpen(myFileName)
If Ret = True Then
MsgBox "Partslist is open, close it and try again"
GoTo Terminate
End If
Set xlapp = oXLApp.Workbooks.Open(myFileName) 'Filename:=file-path, ReadOnly:=True
xlapp.Application.ScreenUpdating = False
'oXLApp.Visible = False
numofrows = LogScheme.firstBlankRow(xlapp)
columnWp = LogScheme.getColumn("WP", xlapp)
columnDrawing = LogScheme.getColumn("Drawing", xlapp)
columnQuantity = LogScheme.getColumn("Quantity", xlapp)
columnCommonName = LogScheme.getColumn("Common", xlapp)
columnMaterial = LogScheme.getColumn("Material", xlapp)
columnMaterialCertificate = LogScheme.getColumn("Certificate", xlapp)
columnCustomerRequirements = LogScheme.getColumn("Customer", xlapp)
columnMOM = LogScheme.getColumn("MOM", xlapp)
columnSerie = LogScheme.getColumn("Serie", xlapp)
columnLogSchema = LogScheme.getColumn("LS", xlapp)
columnSupplierMaterial = LogScheme.getColumn("Location", xlapp)
columnRevision = LogScheme.getColumn("Revision", xlapp)
If numofrows < 3 Or IsEmpty(numofrows) Then
MsgBox "The partslist is empty, no logscheme can be produced"
GoTo Terminate
End If
j = 0
ProgressBar.Show vbModeless
For i = 3 To numofrows
sPercentage = (i/numofrows) * 100
ProgressBar.progress (sPercentage)
If Not IsEmpty(xlapp.sheets("List").Cells(i, columnWp).Value) And IsEmpty(xlapp.sheets("List").Cells(i, columnLogSchema).Value) Then
j = j + 1
Call main.NewFile(3, projectnumber, xlapp.sheets("List").Cells(i, columnCommonName).Value, xlapp.sheets("List").Cells(i, columnDrawing).Value, avsender)
docTemplate = ActiveDocument.Name
'get properties from excel
Documents(docTemplate).CustomDocumentProperties("WP") = xlapp.sheets("List").Cells(i, columnWp).Value
некоторый код, а затем очистки:
Unload ProgressBar
MsgBox "Created " & j & "New Log Schemes"
xlapp.Application.ScreenUpdating = True
xlapp.ActiveWorkbook.Close (True)
xlapp.Quit
Set xlapp = Nothing
Set oXLApp = Nothing
' Do all on the doc out document.....
dokut = FileHandling.getDocOutName(projectnumber)
If FileHandling.openDocument(dokut) Then
Call initGUI.closeGUI
Call searchAll("LS")
Else
MsgBox "Did not find any dokument with that number, sorry mate."
End If
Application.ScreenUpdating = True
Documents(dokut).Activate
Documents(dokut).Save
Terminate:
initGUI.closeGUI
Exit Sub
код использует этот код, чтобы проверить, если файл Excel открыт другим пользователем:
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
и эта функция, чтобы найти первую пустую строку/последнюю строку + 1:
Function firstBlankRow(ByRef xlapp) As Long
'returns the row # of the row after the last used row
With xlapp.sheets("List")
firstBlankRow = .Range("A1").Offset(.Rows.Count - 1, 0).End(xlUp).Row + 1
End With
End Function
Избавьтесь от цикла и использовать 'автофильтр()' 'с SpecialCells()' –
I советовал бы поместить ваши полезные строки в массив, а не в цикле, непосредственно на листе, но не уверен, что будет гораздо больше времени на эффективность ... У вас есть метки времени для разных частей вашего кода? Я использую пользовательский индикатор выполнения, который создает таблицу времени, которая может использоваться для определения того, какая часть кода занимает много времени. Дайте знать, если вас это заинтересовало! – R3uK
[Обзор кода] (http://codereview.stackexchange.com/help/on-topic) содержит более 2500 вопросов с тегом [performance]. – pnuts