I'm trying to call excel's FORECAST.ETS from VBA and I have a for loop which works well for the first 255 iterations and dramatically gets slower from the 256th.
I would be glad if someone can help me. I would also be happy about a better and faster solution.
Public Sub CreateDatabase()
Application.Calculation = XlCalculation.xlCalculationManual
Application.ScreenUpdating = False
Dim i as Long
For i = 1 To 336
With Worksheets("Sheet1")
.Range("AHV" & i + 1 & ":AIS" & i + 1).Formula = "=IFERROR(FORECAST.ETS(Sheet1!AHV$1,Sheet1!$B" & i + 1 & ":$AHU" & i + 1 & ",Sheet1!$B$1:$AHU$1,1),0)"
End With
Application.StatusBar = Format(Round(100 * i / 336, 2), "0.00") & "% - " & i * 24 & " of " & 336 * 24 & " items created"
Next
Application.StatusBar = False
Application.Calculation = XlCalculation.xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Related
I have the following code, that basically copies databases from some files in a folder and pastes in my workbook.
It is supposed to clean everything before starting, and it does when I run from console, hitting F8 and going through it, but when I click the button to which I have assigned the Macro, it does not clean the old base before getting the new ones, then I get old data and then new data below it.
Do you know what can cause it?
Thank you!
Sub Atualizar_B_Un_Time()
Application.ScreenUpdating = False 'speed up macro execution
Application.EnableEvents = False 'turn off other macros for now
Application.DisplayAlerts = False 'turn off system messages for now
Dim base_5 As Workbook
Dim plan_5 As Worksheet
Dim aux As String
Dim caminho As String
Dim nome_arquivo_5 As String
Dim destino_5 As Worksheet
Dim dia As String
Set destino_5 = ThisWorkbook.Worksheets("B_Un_Time")
caminho = Application.ActiveWorkbook.Path
nome_arquivo_5 = Dir(caminho & "\IC_Reports_AgentUnavailableTime*.xlsx")
destino_5.Range("H2:L" & Cells(Rows.Count, "I").End(xlUp).Row).UnMerge
destino_5.Range("F2:F" & Cells(Rows.Count, "F").End(xlUp).Row).ClearContents
destino_5.Range("H2:L" & Cells(Rows.Count, "I").End(xlUp).Row).ClearContents
Do While nome_arquivo_5 <> ""
aux = caminho & "\" & nome_arquivo_5
Set base_5 = Workbooks.Open(aux, Local:=True)
Set plan_5 = base_5.Sheets(1)
dia = Mid(nome_arquivo_5, InStr(nome_arquivo_5, "-") + 1, 2)
plan_5.Range("A2:E" & plan_5.Cells(Rows.Count, "B").End(xlUp).Row).Copy _
Destination:=destino_5.Range("H" & (destino_5.Cells(Rows.Count, "I").End(xlUp).Row + 1))
destino_5.Range("F" & (destino_5.Cells(Rows.Count, "F").End(xlUp).Row + 1) & ":" & "F" & _
(destino_5.Cells(Rows.Count, "I").End(xlUp).Row)).Value = Format(Now, "mm/") & dia & Format(Now, "/yyyy")
base_5.Close savechanges:=False
nome_arquivo_5 = Dir
Loop
If IsEmpty(destino_5.Range("A" & destino_5.Cells(Rows.Count, "I").End(xlUp).Row)) Then
destino_5.Range("A2:E2").Copy Destination:=destino_5.Range("A" & (destino_5.Cells(Rows.Count, "A").End(xlUp).Row + 1) _
& ":" & "E" & destino_5.Cells(Rows.Count, "I").End(xlUp).Row)
destino_5.Range("G2").Copy Destination:=destino_5.Range("G" & (destino_5.Cells(Rows.Count, "G").End(xlUp).Row + 1) & ":" & _
"G" & destino_5.Cells(Rows.Count, "I").End(xlUp).Row)
ElseIf Not IsEmpty(destino_5.Range("A" & (destino_5.Cells(Rows.Count, "I").End(xlUp).Row + 1))) Then
destino_5.Rows((destino_5.Cells(Rows.Count, "I").End(xlUp).Row + 1) & ":" & destino_5.Cells(Rows.Count, "A") _
.End(xlUp).Row).EntireRow.Delete
End If
destino_5.Cells.Font.Name = "Calibri"
destino_5.Cells.Font.Size = 8
destino_5.Rows.RowHeight = 11.25
Application.DisplayAlerts = True 'turn system alerts back on
Application.EnableEvents = True 'turn other macros back on
Application.ScreenUpdating = True 'refreshes the screen
End Sub
It's probably because you haven't added a sheet references everywhere. and hence are referencing the active sheet. Try amending that section thus (note the dots):
With destino_5
.Range("H2:L" & .Cells(.Rows.Count, "I").End(xlUp).Row).UnMerge
.Range("F2:F" & .Cells(.Rows.Count, "F").End(xlUp).Row).ClearContents
.Range("H2:L" & .Cells(.Rows.Count, "I").End(xlUp).Row).ClearContents
End With
I have written the following code; both Sheet 1 and Sheet 2 are rather big sheet with lots of data. Run this Macro is extremely time comsuming ( It has a high complexity I guess). I'm quite new at VBA and therefore having trouble make the code more effective.
Sub Find()
Dim rgFound As Range
Dim Index As Long: Index = 6
Dim Row as Long
Do While Worksheets("Sheet2").Cells(Index, "D").Value > 0
Sheets("Sheet1").Select
Set rgFound = Range("A1:A20000").Find(Worksheets("Sheet2").Cells(Index, "D").Value)
If Not rgFound Is Nothing Then
Row = rgFound.Row
Worksheets("Sheet1").Range("E" & Row).Value = Worksheets("Sheet2").Range("AA" & Index).Value
Worksheets("Sheet1").Range("F" & Row).Value = Worksheets("Sheet2").Range("AB" & Index).Value
Worksheets("Sheet1").Range("G" & Row).Value = Worksheets("Sheet2").Range("AC" & Index).Value
Worksheets("Sheet1").Range("H" & Row).Value = Worksheets("Sheet2").Range("Z" & Index).Value
Worksheets("Sheet1").Range("J" & Row).Value = Worksheets("Sheet2").Range("AG" & Index).Value
Worksheets("Sheet1").Range("I" & Row).Value = Worksheets("Sheet2").Range("AD" & Index).Value
Else
' Function // Not done yet
End If
Index = Index + 1
Loop
End Sub
Is the built in Find function effective? The loop loops trough roughly 250-400 values. Any Ideas?
I have the following code as part of a Job site labor form, which links a full labor call on the "LocLabor" sheet to various single day sign in sheets. This particular code is to add a complete day to the form, and works great, with the exception of these two lines at the bottom:
.Buttons(bnum).ShapeRange.AlternativeText = dayint + 1
.Buttons(bnum + 1).ShapeRange.AlternativeText = dayint + 1
The "scopy", "ecopy", and "brow" variables are used to work out the appropriate lines to copy and paste to the next day. The buttons that are being altered are the newly pasted buttons that were copied within the scopy/ecopy range and are used to add or delete a line from the table they refer to. I need to be able to change the AltText because I am using that as a reference for which day of the labor call they apply to. The "numdays" variable pulls from locsht.Range("L3").Value, which is set to the current number of days on the form prior to running the macro. So it would have a value of 2 when I see the error
Now to the issue - if I have two days existing in the document and I execute the below code, the name of the button changes, but the Alternative Text does not (it remains as "2" or whatever it was prior to copying). Days 4 and up work perfectly though, it is just the transition from day 2 to 3 that I cannot get to work! It also works if I switch out "dayint + 1" to a string, like "banana" for example, but that obviously doesn't help me.
Any ideas would be appreciated.
Option Explicit
Sub add_day()
Dim numdays As String
Dim tbl As TableStyle
Dim newsht As Worksheet
Dim locsht As Worksheet
Dim scopy As Integer
Dim ecopy As Integer
Dim brow As Integer
Dim dayint As Integer
Dim bnum As Integer
Dim tblstart As String
Application.ScreenUpdating = False
'unlock sheet
Worksheets("LocLabor").Unprotect Password:=SuperSecretPW
'set/get variables
Set locsht = Worksheets("LocLabor")
numdays = locsht.Range("L3").Value
dayint = numdays
Worksheets("Labor Sign In Day " & numdays).Copy Before:=Sheets(numdays + 4)
Worksheets("Labor Sign In Day " & numdays & " (2)").Name = "Labor Sign In Day " & numdays + 1
'update number of days on sheet
locsht.Range("L3") = locsht.Range("L3").Value + 1
'rename new sign in sheet
Set newsht = Worksheets("Labor Sign In Day " & numdays + 1)
newsht.Unprotect Password:=SuperSecretPW
'figure out which rows to copy on main sheet
scopy = locsht.ListObjects(dayint).Range.Rows(1).Row - 1
brow = locsht.ListObjects(dayint).Range.Rows.Count
ecopy = scopy + brow
'Copy/paste new day on LocLabor
locsht.Activate
locsht.Rows(scopy & ":" & ecopy).Copy
locsht.Rows(ecopy + 2).Insert Shift:=xlDown
locsht.ListObjects("Tableday" & numdays).Resize Range("A" & scopy + 1 & ":" & "H" & ecopy)
locsht.Range("A" & ecopy + 2 & ":" & "H" & ecopy + 2) = "=IFERROR($A$17+" & numdays & "," & """Enter Load in Date at Top"")"
locsht.Rows(ecopy + 1).EntireRow.Delete
locsht.PageSetup.PrintArea = "$A$1:$H$" & ecopy + (ecopy - scopy + 1)
locsht.HPageBreaks.Add Before:=locsht.Rows(ecopy + 1)
locsht.ListObjects(dayint + 1).Name = "Tableday" & numdays + 1
bnum = (dayint * 2) + 3
tblstart = locsht.ListObjects(dayint + 1).Range.Rows(1).Row + 1
'Enter correct formulas into sign in sheet
With newsht
.ListObjects(1).Name = "signinday" & numdays + 1
.Range("i12") = Left(newsht.Range("i12").Formula, 28) & numdays & Right(newsht.Range("i12").Formula, 48)
.Range("A17") = "=IF(ISBLANK(LocLabor!G" & tblstart & ")=FALSE,LocLabor!G" & tblstart & "&"" ""&LocLabor!F" _
& tblstart & ",IF(ISBLANK(LocLabor!D" & tblstart & ")=TRUE," & """""" & ",LocLabor!D" & tblstart & "))"
.Range("B17") = "=IF(ISBLANK(LocLabor!B" & tblstart & ")=TRUE, """", LocLabor!B" & tblstart & ")"
.Range("G17") = "=IF(ISBLANK(LocLabor!C" & tblstart & ")=TRUE, """", LocLabor!C" & tblstart & ")"
End With
'rename pasted buttons, update alttext
With locsht
.Buttons(bnum).Name = "Button " & bnum
.Buttons(bnum + 1).Name = "Button " & bnum + 1
.Buttons(bnum).ShapeRange.AlternativeText = dayint + 1
.Buttons(bnum + 1).ShapeRange.AlternativeText = dayint + 1
End With
'lock down sheets
Worksheets("LocLabor").Protect Password:=SuperSecretPW, DrawingObjects:=False, Contents:=True, Scenarios:=True _
, AllowFormattingCells:=True, AllowFormattingRows:=True, _
AllowInsertingRows:=True, AllowDeletingRows:=True, AllowSorting:=True, _
AllowFiltering:=True
Worksheets("LocLabor").EnableSelection = xlUnlockedCells
Worksheets("Labor Sign In Day " & numdays + 1).Protect Password:=SuperSecretPW, DrawingObjects:=False, Contents:=True, Scenarios:=True _
, AllowFormattingCells:=True, AllowFormattingRows:=True, _
AllowInsertingRows:=True, AllowDeletingRows:=True, AllowSorting:=True, _
AllowFiltering:=True
Worksheets("Labor Sign In Day " & numdays + 1).EnableSelection = xlUnlockedCells
ActiveSheet.Buttons(Application.Caller).TopLeftCell.Offset(3, 0).Select
Application.ScreenUpdating = True
End Sub
I Hvae the following code:
Public Sub CiscoPrimeReport111()
Dim rowCounter As Long
Dim colCounter As Long
Dim throughputAP As Long
throughputAP = 2
rowCounter = 8
colCounter = 1
MsgBox ("Please do the following before pressing the OK BUtton on this Popup Window!!:" & vbNewLine & vbNewLine & _
"1. Open the CISCO PRIME AP Report you want to use" & vbNewLine & _
"2. Select all the data (Ctrl + A)" & vbNewLine & _
"3. Copy ALL the content (Ctrl + C)" & vbNewLine & _
"4. NOW YOU CAN PRESS THE OK BUTTON!")
Application.DisplayAlerts = False
Call createCiscoSheet
With ThisWorkbook.Sheets("Cisco Raw")
.Range("A1").PasteSpecial (xlPasteValues)
With ThisWorkbook.ActiveSheet.Rows(rowCounter)
Do Until Cells(rowCounter, colCounter).Value = "AP Statistics Summary"
ThisWorkbook.Sheets("Throughput Per AP").Rows(throughputAP).Resize(1, .Columns.Count - 1).Offset(0, 1).Value = _
.Rows(throughputAP).Value '.Resize(1, .Columns.Count - 1).Value
throughputAP = throughputAP + 1
rowCounter = rowCounter + 1
Loop
End With
End With
End Sub
the code runs well and the'Do Until' loop runs well too but it is not stoping when the following condition is met:
Do Until Cells(rowCounter, colCounter).Value = "AP Statistics Summary"
it just keeps on looping until the end of the source sheet.
any ideas why? i am a noob at this so any help is appreciate it!
I have a VBA script that copies data from rows in the SoapUI - Single Sheet to a STpremcalc Sheet and then copies the final calculation back over to SoapUI - Single Sheet. It works fine but I have 10000 rows of data and it takes around 30 seconds to do one row. When I tested it with 1000 rows it finished within a minute.
What is causing this? Is it because the VBA script is reading the whole worksheet before if copies the values across.
Sub SingleRating()
Dim i As Long
Dim iteration As Variant
Dim seleciton As Variant
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Worksheets("SoapUI - Single")
Set ws2 = Worksheets("STpremcalc")
iteration = 0
iteration = InputBox("Please Select Row Iteration", "", "1000")
seleciton = iteration + 2
For i = 3 To seleciton
ws2.Range("B3").Value = ws1.Range("B" & i).Value
ws2.Range("B4").Value = ws1.Range("C" & i).Value
ws2.Range("B5").Value = ws1.Range("D" & i).Value
ws2.Range("B6").Value = ws1.Range("E" & i).Value
ws2.Range("E3").Value = ws1.Range("F" & i).Value
ws2.Range("E4").Value = ws1.Range("G" & i).Value
ws2.Range("E5").Value = ws1.Range("H" & i).Value
ws2.Range("E6").Value = ws1.Range("I" & i).Value
ws2.Range("G3").Value = ws1.Range("J" & i).Value
ws2.Range("G4").Value = ws1.Range("K" & i).Value
ws2.Range("G5").Value = ws1.Range("L" & i).Value
ws2.Range("J3").Value = ws1.Range("N" & i).Value
ws2.Range("J4").Value = ws1.Range("O" & i).Value
ws2.Range("J6").Value = ws1.Range("P" & i).Value
ws2.Range("B9:E9").Value = ws1.Range("Q" & i, "T" & i).Value
ws2.Range("B10:E10").Value = ws1.Range("U" & i, "X" & i).Value
ws2.Range("B11:E11").Value = ws1.Range("Y" & i, "AB" & i).Value
ws2.Range("B12:E12").Value = ws1.Range("AC" & i, "AF" & i).Value
ws2.Range("B13:E13").Value = ws1.Range("AG" & i, "AJ" & i).Value
ws2.Range("B14:E14").Value = ws1.Range("AK" & i, "AN" & i).Value
ws2.Range("B15:E15").Value = ws1.Range("AO" & i, "AR" & i).Value
ws2.Range("B16:E16").Value = ws1.Range("AS" & i, "AV" & i).Value
'''''''''''''''''''''''''''''''''''''''''''''''''
ws1.Range("AW" & i).Value = ws2.Range("M4").Value
ws1.Range("AX" & i).Value = ws2.Range("M5").Value
ws1.Range("AY" & i).Value = ws2.Range("M6").Value
Application.StatusBar = "Current iteration: " & (i - 2) & "/" & iteration
Next i
End Sub
If that is your whole code I'd suggest inserting this right after initializing your variables:
screenUpdateState = Application.ScreenUpdating
statusBarState = Application.DisplayStatusBar
calcState = Application.Calculation
eventsState = Application.EnableEvents
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
At the very end of your code (above End Sub) reverse it:
Application.ScreenUpdating = screenUpdateState
Application.DisplayStatusBar = statusBarState
Application.Calculation = calcState
Application.EnableEvents = eventsState
From my experience especially the ScreenUpdating part gives a massive performance boost when copying / inserting rows. If you still have performance problems after disabling it, we need to look at the implementation itself.
I think this should help you though, as I have copied tens of thousand rows between worksheets and never had a performance issue.