Slow .value function within for loop - performance

I have been using this site for a while and it has been really useful for me. First of all I want to thank all contributors for this. However I faced a problem and could not find a solution for that.
I'm not a professional coder or programmer, I am only using excel VBA to improve some reporting tools which we use at work. That is why I may have done really basic mistakes, please do not hate me :)
So, I am trying to create basic inventory follow-up tool which is going to contain some part numbers in the main sheet (Followup Sheet) and every day responsible is going to paste some values to incoming sheet (WebDOS Pivot), with my macro I am planning to look for incoming part numbers within existing ones and if it is there input the incoming value to the related cell.
My .find function is working good, however when I add the code to copy the value to related cell macro starts to run really slow. Do you guys have any idea what I am doing wrong, or how can I improve the performance of this code? Thank you in advance.
Dim WebDOSLastRow As Long
Dim WDS As Worksheet
Dim FUS As Worksheet
Dim PUS As Worksheet
Dim SearchResult As Range
Set WDS = Sheets("WebDOS Pivot")
Set FUS = Sheets("Followup Sheet")
Set PUS = Sheets("Part Usage Pivot")
WebDOSLastRow = WDS.Range("A3").End(xlDown).Row
For i = 5 To WebDOSLastRow - 1
With FUS.Range("E:E")
Set SearchResult = .Find(What:=WDS.Range("A" & i).Value, _
After:=Range("E5"), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not SearchResult Is Nothing Then
FUS.Range("K" & SearchResult.Row).Value = WDS.Range("C" & i).Value + FUS.Range("K" & SearchResult.Row).Value
Else
'Coding Will Come Here for not found items
End If
End With
Application.StatusBar = "Searching " & i & "/" & WebDOSLastRow
Next
Application.StatusBar = False
End Sub

I have managed to solve my problem right after posting here, which shows that I did not try hard before :), so simply switching to manual calculation solved slow running problem. Here is the new code.
WebDOSLastRow = WDS.Range("A3").End(xlDown).Row
Application.Calculation = xlCalculationManual '<---- Switching to manual calculation
For i = 5 To WebDOSLastRow - 1
With FUS.Range("E:E")
Set SearchResult = .Find(What:=WDS.Range("A" & i).Value, _
After:=Range("E5"), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not SearchResult Is Nothing Then
FUS.Range("K" & SearchResult.Row).Value = WDS.Range("C" & i).Value + FUS.Range("K" & SearchResult.Row).Value
Else
'Coding Will Come Here for not found items
End If
End With
Application.StatusBar = "Searching " & i & "/" & WebDOSLastRow
Next
Application.StatusBar = False
Application.Calculation = xlCalculationAutomatic

Related

Excel-VBA: High performance sheet update

I have a working code that updates cell entries in Sheet "B" with reference to entries in Sheet "A". However, the code is slow (the tables are really huge). Can anybody show me how to do it more efficiently?
Sub UpdateList()
Dim i As Integer
Dim c As Range
Application.ScreenUpdating = False
For i = 1 to 1000
For Each c in Sheets("A").Range("C8:C10000").Cells
If c.value = i Then
Sheets("B").Range("D" & i) = Sheets("B").Range("D" & i).value & "; " _
& Sheets("A").Range("X" & c.Row).value
End if
Next c
Next i
Application.ScreenUpdating = True
End
I am curious what I could do better. Thanks!

Improve Looping Efficiency in VBA

I have a For loop that loops through integers 1 to 9 and simply finds the bottom most entry that corresponds to that integer ( i.e. 1,1,1,2,3,4,5 would find the 3rd "1" entry) and inserts a blank row. I concatenate the number with a string "FN" that just corresponds to the application for this code, just to clarify. Anyway, it works well, but it lags quite a bit for only having to run through 9 integers. I was hoping someone would be able to help me debug to improve speed on this code. Thanks!
Bonus points if anyone can shed some light on a good way to populate the blank row being inserted with a formatted copy of the header of the page that spans ("A1:L1"). The code I attempted is commented out right before Next i.
Sub test()
Dim i As Integer, Line As String, Cards As Range
Dim Head As Range, LR2 As Long
For i = 1 To 9
Line = "FN" & CStr(i)
Set Cards = Sheets(1).Cells.Find(Line, after:=Cells(1, 1), searchdirection:=xlPrevious)
Cards.Rows.Offset(1).EntireRow.Insert
Cards.Offset(1).EntireRow.Select
' Range("A" & (ActiveCell.Row), "K" & (ActiveCell.Row)) = Range("A3:K3")
' Range("A" & (ActiveCell.Row), "K" & (ActiveCell.Row)).Font.Background = Range("A3:K3").Font.Background
Next i
End Sub
This works pretty fast for me
Sub Sample()
Dim i As Long, line As String, Cards As Range
With Sheets(1)
For i = 1 To 9
line = "FN" & i
Set Cards = .Columns(6).Find(line, LookIn:=xlValues, lookat:=xlWhole)
If Not Cards Is Nothing Then
.Range("A3:K3").Copy
Cards.Offset(1, -5).Insert Shift:=xlDown
End If
Next i
End With
End Sub
Before
After
Most of your improvements will come from altering the application environment variables with the appTGGL helper function but there are a few tweaks in the base code here.
Option Explicit
Sub ewrety()
Dim f As Long, fn0 As String, fndfn As Range
'appTGGL btggl:=false 'uncomment this when you are confident in it
With Worksheets(1).Columns("F")
For f = 1 To 9
fn0 = Format$(f, "\F\N0")
Set fndfn = .Find(What:=fn0, After:=.Cells(1), LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
With fndfn
.Offset(1, -5).EntireRow.Insert Shift:=xlDown
.Parent.Range("A1:L1, XFC1").Copy Destination:=.Offset(1, -5)
End With
Next f
End With
appTGGL
End Sub
Public Sub appTGGL(Optional bTGGL As Boolean = True)
With Application
.ScreenUpdating = bTGGL
.EnableEvents = bTGGL
.DisplayAlerts = bTGGL
.AutoRecover.Enabled = bTGGL 'no interruptions with an auto-save
.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
.CutCopyMode = False
.StatusBar = vbNullString
End With
Debug.Print Timer
End Sub

Macro to filter data and then insert formula onto visible cells

I am trying to filter a worksheet (via Column DL). I then need to insert a formula into Column DQ but only for the visible cells. I was previously using the code below which works except I do not want the specific reference to cell DQ3. This cell can change and thus the wrong formula is copied and pasted.
Dim LastRow As Long
Dim FinalRow As Long
LastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("DL2:DL" & LastRow).AutoFilter Field:=116, Criteria1:= _
"ABC"
Range("DQ3").Copy
FinalRow = Cells(Rows.Count, "B").End(xlUp).Row
Range("DQ3:DQ" & FinalRow).Select
ActiveSheet.Paste
I tried the code below but it returns a "Run-time error '1004': Application-defined or object-defined error on the final line of code:
Dim LastRow As Long
Dim FinalRow As Long
LastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("DL2:DL" & LastRow).AutoFilter Field:=116, Criteria1:= _
"ABC"
FinalRow = Range("B" & Rows.Count).End(xlUp).Row
Range("DQ2:DQ" & FinalRow).FormulaR1C1 = "=(RC[-1]-RC[-2])"
I also tried this code:
Dim LastRow As Long
Dim FinalRow As Long
LastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("DL2:DL" & LastRow).AutoFilter Field:=116, Criteria1:= _
"ABC"
FinalRow = Range("B" & Rows.Count).End(xlUp).Row
Set RNG = Range("DQ2:DQ" & FinalRow).SpecialCells(xlCellTypeVisible)
RNG = "=(RC[-1]-RC[-2])"
This runs without any errors but does not fill any data into Column DQ.
Any suggestions on how to get rid of the error or how to achieve my original goal? I am not sure what I am trying will even work but this is where I got stuck.
Thanks!
I was able to achieve my goal using the code below. Posting in case someone else has the same issue in the future.
With ActiveSheet.Range("DQ2:DQ" & Cells(Rows.Count,2).End(xlUp).Row).SpecialCells(xlCellTypeVisible)
.Cells.FormulaR1C1 = "=((RC[-1]-RC[-2])"`
.Cells.FillDown`
Worksheets("WorksheetName").Columns(10).Calculate
End With
Cheers!

VBA windows to mac

I made a code on my Windows PC, have multiple macro's/VBA's but made the file for somebody with an Mac.
not sure where to start with adjusting code, but has anyone a clue how the following problems are caused, this will help me with finding a solution.. I probably used windows specific components..
if somebody can push me in the right direction, it would be great.. Have found a few topics:
http://www.vbaexpress.com/forum/archive/index.php/t-12976.html
and this one probably has the solution for my PDF problem:
Excel VBA code to work on Mac, Create PDF Function
Problem 1: colomnwidth doesn't work:
End With
Columns("A:A").EntireColumn.AutoFit
Columns("A:A").ColumnWidth = 26
Columns("C:H").Select
Selection.ColumnWidth = 4.5
Columns("J:L").Select
Selection.ColumnWidth = 11.5
Columns("I:I").Select
Selection.ColumnWidth = 16.25
Columns("B:B").ColumnWidth = 11.5
Columns("J:L").Select
Selection.ColumnWidth = 10.25
Columns("I:I").EntireColumn.AutoFit
Button to make PDF gives "Could not Create PDF"
Sub SaveConcept()
Dim ws As Worksheet
Dim strPath As String
Dim myFile As Variant
Dim strFile As String
On Error GoTo errHandler
Range("N8:N9").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 5287936
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveSheet.PageSetup.Orientation = xlLandscape
Set ws = ActiveSheet
strFile = Range("J15") _
& Format(Now(), " dd-mm-yyyy") _
& Format(" Concept") _
& ".pdf"
strFile = ThisWorkbook.Path & "\" & strFile
myFile = Application.GetSaveAsFilename _
(InitialFileName:=strFile, _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Select Folder and FileName to save")
If myFile <> "False" Then
ActiveSheet.Range("L1", _
ActiveSheet.Range("L1").End(xlDown).End(xlDown).End(xlDown).End(xlToLeft).End(xlToLeft).End(xlToLeft).End(xlDown)).ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=myFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
End If
exitHandler:
Exit Sub
errHandler:
MsgBox "Could not create PDF file"
Resume exitHandler
End Sub
thanks
There shouldn't be an issue with the first part+ as it's nothing specific to windows, for the second part - you're using "\" as the path separator for the PDF file, on a Mac this is typically ":"
To make the code compatible for both, use the application value instead:
strFile = ThisWorkbook.Path & Application.PathSeparator & strFile
+note: this was OP code at time of answer

Couldnt connect to Oracle Database using VB script

Hi Please help me with the following. I used the below VB code to upload a text file to my oracle database.When i run my script i have the error message "Class not defined ADODB"
Set Obj_DBConn = New ADODB.Connection
Set cat = New ADOX.Catalog
Obj_DBConn.ConnectionString ="Driver={Microsoft ODBC for Oracle}; " & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=TCP)" & _
"(HOST=##test##)(PORT=##test##))" & _
"(CONNECT_DATA=(SERVICE_NAME=##test##))); " & _
"uid=test;pwd=test;"
Obj_DBConn.Open Database_Path
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = Nothing
Set f = fso.OpenTextFile("C:\Documents and Settings\test.txt", ForReading, True)
For i = 1 To 10000
v_Line_String = f.ReadLine
v_Output_Each_part = Split(v_Line_String,";",-1,1)
v_Col_A = v_Output_Each_part(0)
v_Col_B = v_Output_Each_part(1)
v_Col_C = v_Output_Each_part(2)
Obj_DBConn.Execute "INSERT INTO test_me (ID_Q, NAME, ROLLNO) VALUES ('" & v_Output_Each_part(0) & "','" & v_Output_Each_part(1) & "','" & v_Output_Each_part(2) & "')"
Next
Please provide ur insights Thanks in advance
Your
Set Obj_DBConn = New ADODB.Connection
is VBA, not VBScript. Use
Set Obj_DBConn = CreateObject("ADODB.Connection")
to get this line passed the interpreter.
If you promise to delete the evil "On Error Resume Next", you may obtain further inspiration from here.
Update:
If you google for something like "80004005 odbc oracle" you'll find this trouble shooter with detailed step by step instructions to deal with connectivity problems. Next stop probably should be connectionstrings.com.

Resources