Related
Need to compare data in two excel files by FacilityID column. Excel A data has to be aggregated first. In Excel B, FacilityID is unique row.
Tries VLOOKUP. It's getting too confusing. Need VBA solution
Function BrowseWin(mypath As String)
With Application.FileDialog(msoFileDialogOpen)
.InitialFileName = GetDir(mypath)
If .Show = -1 Then
BrowseWin = .SelectedItems.Item(1)
Else
BrowseWin = "-"
End If
End With
End Function
Function BrowseMac(mypath As String) As String
sMacScript = "set applescript's text item delimiters to "","" " & vbNewLine & _
"try " & vbNewLine & _
"set theFiles to (choose file " & _
"with prompt ""Please select a file or files"" default location alias """ & _
mypath & """ multiple selections allowed true) as string" & vbNewLine & _
"set applescript's text item delimiters to """" " & vbNewLine & _
"on error errStr number errorNumber" & vbNewLine & _
"return errorNumber " & vbNewLine & _
"end try " & vbNewLine & _
"return theFiles"
BrowseMac = MacScript(sMacScript)
End Function
Function grantFileAccess(filePermissionCandidates)
grantFileAccess = GrantAccessToMultipleFiles(filePermissionCandidates)
End Function
Public Function GetDir(File) As String
If Application.OperatingSystem Like "*Mac*" Then
div = ":"
Else
div = "\"
End If
x = InStrRev(File, div)
If x = 0 Then
GetDir = File
Else
GetDir = Left(File, x)
End If
End Function
Sub ChooseOptima_Click()
Dim startDir As String
startDir = GetDir("/")
If Application.OperatingSystem Like "*Mac*" Then
Path = BrowseMac(startDir)
If Path = "-43" Or Path = "-1700" Then
startDir = MacScript("return (path to documents folder) as String")
Path = BrowseMac(startDir)
End If
Else
Path = BrowseWin(startDir)
End If
If Left(Path, 1) <> "-" Then
Range("Optimafile") = Path
Range("C6").Select
End If
End Sub
Sub ChooseCRC_Click()
Dim startDir As String
startDir = GetDir("/")
If Application.OperatingSystem Like "*Mac*" Then
Path = BrowseMac(startDir)
If Path = "-43" Or Path = "-1700" Then
startDir = MacScript("return (path to documents folder) as String")
Path = BrowseMac(startDir)
End If
Else
Path = BrowseWin(startDir)
End If
If Left(Path, 1) <> "-" Then
Range("Crcfile") = Path
Range("A9").Select
End If
End Sub
Sub LoadReports()
Application.ScreenUpdating = False
With Worksheets("Sheet1")
ResultPath = Range("Optimafile").Value
grantAccessReq = Application.OperatingSystem Like "*Mac*"
If grantAccessReq Then
filePermissionCandidates = Array(NormPath, ExprPath)
grantFileAccess (filePermissionCandidates)
End If
CopyToReport (ResultPath)
End With
End Sub
Sub CopyToReport(OptimaPath As String)
Dim Sheet1, Sheet2 As Worksheet
Dim CrcPath, File1, File2 As String
File1 = Right$(OptimaPath, Len(OptimaPath) - InStrRev(OptimaPath, "\"))
CrcPath = Range("CrcFile").Value
File2 = Right$(CrcPath, Len(CrcPath) - InStrRev(CrcPath, "\"))
Application.DisplayAlerts = False
For Each ws In Worksheets
If ws.Name = "Optima Blue" Then
Sheets("Optima Blue").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "Optima Green" Then
Sheets("Optima Green").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "CRC Limit" Then
Sheets("CRC Limit").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "CRC Usage" Then
Sheets("CRC Usage").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "Result Limit" Then
Sheets("Result Limit").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "Result Usage" Then
Sheets("Result Usage").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "CRC Usage Consolidated" Then
Sheets("CRC Usage Consolidated").Delete
End If
Next
For Each ws In Worksheets
If ws.Name = "CRC Limit Consolidated" Then
Sheets("CRC Limit Consolidated").Delete
End If
Next
Application.DisplayAlerts = True
Workbooks.Open (OptimaPath)
Set Sheet1 = Workbooks(File1).Worksheets(1)
MakeOptimaBlueSheet
MakeOptimaGreenSheet
CloseBook (File1)
Workbooks.Open (CrcPath)
Set Sheet2 = Workbooks(File2).Worksheets("CRC")
MakeCRCSheetLimit
MakeCRCSheetUsage
CloseBook (File2)
MakeCRCSheetUsageConsolidated
MakeCRCSheetLimitConsolidated
MakeResultOptimaBlue
MakeResultOptimaGreen
MakeResultLimitReport
MakeResultUsageReport
End Sub
Sub MakeOptimaBlueSheet()
dlastRow = ActiveSheet.Cells(Rows.Count, "I").End(xlUp).Row
Dim rng, aRng, bRng As Range
Dim i, a, hSearch, head, headerCount As Integer
Set FirstCellExclude = ThisWorkbook.Sheets("Sheet1").Range("FirstCellExcludeHeader")
Set SecondCellExclude = ThisWorkbook.Sheets("Sheet1").Range("SecondCellExcludeHeader")
Set OptimaBlueHeaders = ThisWorkbook.Sheets("Sheet1").Range("OptimaBlueHeaders")
Set FindHeaders = ActiveSheet.Range("A1:ZZ1")
Set u = Union(FirstCellExclude, OptimaBlueHeaders, SecondCellExclude)
For Each fcell In FindHeaders
For Each oCell In u
If IsEmpty(fcell) Or IsEmpty(oCell) Then
ElseIf fcell = oCell Then
If Not IsEmpty(strRange) Then strRange = strRange + ","
Cell_Add = Split(fcell.Address, "$")
strRange = strRange + Cell_Add(1) + "1:" + Cell_Add(1) + CStr(dlastRow)
headerCount = headerCount + 1
Else
End If
Next oCell
Next fcell
ActiveSheet.Range(strRange).Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Optima Blue"
ws.Paste
Set ws2 = ThisWorkbook.Sheets("Sheet1")
Set ExcludeRng = ws2.Range("FirstCellValues")
exclLastRow = ws2.Range("FirstCellValues").Rows.Count
Set searchFilterLetter = ws.Range("A1:Z1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = FirstCellExclude.Value Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Debug.Print FilterLetter
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
Set searchFilterLetter = ws.Range("A1:Z1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = SecondCellExclude.Value Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Debug.Print FilterLetter
Else
End If
Next gcell
Set ExcludeRng2 = ws2.Range("SecondCellValues")
exclLastRow2 = ws2.Range("SecondCellValues").Rows.Count
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow2 To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng2.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng2.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
ws.Range("G1") = "Optima Blue Total"
ws.Range("G2").Formula = "=B2+C2+D2+E2+F2"
ws.Range("G2").Copy
ws.Range("G3:G" & dlastRow & " ").PasteSpecial (xlPasteAll)
ws.Range("G2:G" & dlastRow & " ").NumberFormat = "#,##0"
For Each rng In ws.Range("G2:G" & dlastRow & " ")
If rng.HasFormula Then
rng.Formula = rng.Value
End If
Next rng
ws.Range("B:F").Delete
End With
End Sub
Sub MakeOptimaGreenSheet()
dlastRow = ActiveSheet.Cells(Rows.Count, "I").End(xlUp).Row
Dim rng As Range
Dim i, a, hSearch, head, headerCount As Integer
Set FirstCellExclude = ThisWorkbook.Sheets("Sheet1").Range("FirstCellExcludeHeader")
Set SecondCellExclude = ThisWorkbook.Sheets("Sheet1").Range("SecondCellExcludeHeader")
Set OptimaGreenHeaders = ThisWorkbook.Sheets("Sheet1").Range("OptimaGreenHeaders")
Set FindHeaders = ActiveSheet.Range("A1:ZZ1")
Set u = Union(FirstCellExclude, SecondCellExclude, OptimaGreenHeaders)
For Each fcell In FindHeaders
For Each oCell In u
If IsEmpty(fcell) Or IsEmpty(oCell) Then
ElseIf fcell = oCell Then
If Not IsEmpty(strRange) Then strRange = strRange + ","
Cell_Add = Split(fcell.Address, "$")
strRange = strRange + Cell_Add(1) + "1:" + Cell_Add(1) + CStr(dlastRow)
headerCount = headerCount + 1
Else
End If
Next oCell
Next fcell
ActiveSheet.Range(strRange).Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Optima Green"
ws.Paste
Set ws2 = ThisWorkbook.Sheets("Sheet1")
Set ExcludeRng = ws2.Range("FirstCellValues")
exclLastRow = ws2.Range("FirstCellValues").Rows.Count
Set searchFilterLetter = ws.Range("A1:Z1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = FirstCellExclude.Value Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Debug.Print FilterLetter
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
Set searchFilterLetter = ws.Range("A1:Z1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = SecondCellExclude.Value Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Debug.Print FilterLetter
Else
End If
Next gcell
Set ExcludeRng2 = ws2.Range("SecondCellValues")
exclLastRow2 = ws2.Range("SecondCellValues").Rows.Count
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow2 To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng2.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng2.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
ws.Range("G1") = "Optima Green Total"
ws.Range("G2").Formula = "=B2+C2+D2+E2+F2"
ws.Range("G2").Copy
ws.Range("G3:G" & dlastRow & " ").PasteSpecial (xlPasteAll)
ws.Range("G2:G" & dlastRow & " ").NumberFormat = "#,##0"
For Each rng In ws.Range("G2:G" & dlastRow & " ")
If rng.HasFormula Then
rng.Formula = rng.Value
End If
Next rng
ws.Range("B:F").Delete
End With
End Sub
Sub MakeCRCSheetLimit()
dlastRow = ActiveSheet.Cells(Rows.Count, "D").End(xlUp).Row
Dim rng As Range
Dim i, a, hSearch, head, headerCount As Integer
Set FirstCrcFilter = ThisWorkbook.Sheets("Sheet1").Range("FirstCrcFilterHeader")
Set SecondCrcFilter = ThisWorkbook.Sheets("Sheet1").Range("SecondCrcFilterHeader")
Set CrcLimitHeaders = ThisWorkbook.Sheets("Sheet1").Range("CrcLimitHeaders")
Set FindHeaders = ActiveSheet.Range("A1:ZZ1")
Set u = Union(CrcLimitHeaders, FirstCrcFilter, SecondCrcFilter)
For Each fcell In FindHeaders
For Each oCell In u
If IsEmpty(fcell) Or IsEmpty(oCell) Then
ElseIf fcell = oCell Then
If Not IsEmpty(strRange) Then strRange = strRange + ","
Cell_Add = Split(fcell.Address, "$")
strRange = strRange + Cell_Add(1) + "1:" + Cell_Add(1) + CStr(dlastRow)
headerCount = headerCount + 1
Else
End If
Next oCell
Next fcell
ActiveSheet.Range(strRange).Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "CRC Limit"
ws.Paste
Set ws2 = ThisWorkbook.Sheets("Sheet1")
Set ExcludeRng = ws2.Range("FirstCrcFilterValues")
exclLastRow = ws2.Range("FirstCrcFilterValues").Rows.Count
Set searchFilterLetter = ws.Range("A1:Zz1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = FirstCrcFilter Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
Set ExcludeRng2 = ws2.Range("SecondCrcFilterValues")
exclLastRow2 = ExcludeRng2.Rows.Count
Set searchFilterLetter = ws.Range("A1:Zz1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = SecondCrcFilter Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow2 To 1 Step -1
Debug.Print ws.Cells(i, FilterLetter), ExcludeRng2.Cells(a, 1)
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng2.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng2.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
ws.Range("B2:B" & dlastRow & " ").NumberFormat = "#,##0"
End With
End Sub
Sub MakeCRCSheetUsage()
dlastRow = ActiveSheet.Cells(Rows.Count, "D").End(xlUp).Row
Dim rng As Range
Dim i, a, hSearch, head, headerCount As Integer
Set FirstCrcFilter = ThisWorkbook.Sheets("Sheet1").Range("FirstCrcFilterHeader")
Set SecondCrcFilter = ThisWorkbook.Sheets("Sheet1").Range("SecondCrcFilterHeader")
Set CrcLimitHeaders = ThisWorkbook.Sheets("Sheet1").Range("CrcUsageHeaders")
Set FindHeaders = ActiveSheet.Range("A1:ZZ1")
Set u = Union(CrcLimitHeaders, FirstCrcFilter, SecondCrcFilter)
For Each fcell In FindHeaders
For Each oCell In u
If IsEmpty(fcell) Or IsEmpty(oCell) Then
ElseIf fcell = oCell Then
If Not IsEmpty(strRange) Then strRange = strRange + ","
Cell_Add = Split(fcell.Address, "$")
strRange = strRange + Cell_Add(1) + "1:" + Cell_Add(1) + CStr(dlastRow)
headerCount = headerCount + 1
Else
End If
Next oCell
Next fcell
ActiveSheet.Range(strRange).Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "CRC Usage"
ws.Paste
Set ws2 = ThisWorkbook.Sheets("Sheet1")
Set ExcludeRng = ws2.Range("FirstCrcFilterValues")
exclLastRow = ws2.Range("FirstCrcFilterValues").Rows.Count
Set searchFilterLetter = ws.Range("A1:Zz1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = FirstCrcFilter Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
Set ExcludeRng2 = ws2.Range("SecondCrcFilterValues")
exclLastRow2 = ExcludeRng2.Rows.Count
Set searchFilterLetter = ws.Range("A1:Zz1")
For Each gcell In searchFilterLetter
If IsEmpty(gcell) Then
ElseIf gcell = SecondCrcFilter Then
Cell_Add = Split(gcell.Address, "$")
FilterLetter = Cell_Add(1)
Else
End If
Next gcell
For i = ws.Range(FilterLetter + "2:" & FilterLetter & dlastRow & " ").Cells.Count To 1 Step -1
For a = exclLastRow2 To 1 Step -1
If IsEmpty(ws.Cells(i, FilterLetter)) Or IsEmpty(ExcludeRng2.Cells(a, 1)) Then
ElseIf ws.Cells(i, FilterLetter) = ExcludeRng2.Cells(a, 1) Then
ws.Cells(i, FilterLetter).EntireRow.Delete
Else
End If
Next a
Next i
ws.Range(FilterLetter + "1:" & FilterLetter & dlastRow & " ").Delete
ws.Range("B2:B" & dlastRow & " ").NumberFormat = "#,##0"
End With
End Sub
Sub MakeCRCSheetUsageConsolidated()
Dim CRCSheetUsageConsolidated As Worksheet, Result As Worksheet
Dim ConsolidateRangeArray As Variant
Set CRCSheetUsageConsolidated = Sheets("CRC Usage")
CRCSheetUsageConsolidated.Select
dlastRow = CRCSheetUsageConsolidated.Cells(Rows.Count, "A").End(xlUp).Row
CRCSheetUsageConsolidated.Select
CRCSheetUsageConsolidated.Range("A1:A" & dlastRow & " ").Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "CRC Usage Consolidated"
Selection.Consolidate Sources:= _
"'CRC Usage'!R1C1:R" & dlastRow & "C2", Function:= _
xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
End With
End Sub
Sub MakeCRCSheetLimitConsolidated()
Dim CRCSheetLimitConsolidated As Worksheet, Result As Worksheet
Dim ConsolidateRangeArray As Variant
Set CRCSheetLimitConsolidated = Sheets("CRC Limit")
CRCSheetLimitConsolidated.Select
dlastRow = CRCSheetLimitConsolidated.Cells(Rows.Count, "A").End(xlUp).Row
CRCSheetLimitConsolidated.Select
CRCSheetLimitConsolidated.Range("A1:A" & dlastRow & " ").Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "CRC Limit Consolidated"
Selection.Consolidate Sources:= _
"'CRC Limit'!R1C1:R" & dlastRow & "C2", Function:= _
xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
End With
End Sub
Sub MakeResultOptimaBlue()
Dim OptimaBlue As Worksheet, Result As Worksheet
Dim ConsolidateRangeArray As Variant
Set OptimaBlue = Sheets("Optima Blue")
OptimaBlue.Select
dlastRow = OptimaBlue.Cells(Rows.Count, "A").End(xlUp).Row
OptimaBlue.Range("A1:A" & dlastRow & " ").Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Result Limit"
Selection.Consolidate Sources:= _
"'Optima Blue'!R1C1:R" & dlastRow & "C2", Function:= _
xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
End With
End Sub
Sub MakeResultOptimaGreen()
Dim OptimaGreen As Worksheet, Result As Worksheet
Dim ConsolidateRangeArray As Variant
Set OptimaGreen = Sheets("Optima Green")
OptimaGreen.Select
dlastRow = OptimaGreen.Cells(Rows.Count, "A").End(xlUp).Row
OptimaGreen.Range("A1:A" & dlastRow & " ").Select
Selection.Copy
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Result Usage"
Selection.Consolidate Sources:= _
"'Optima Green'!R1C1:R" & dlastRow & "C2", Function:= _
xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
End With
End Sub
Sub MakeResultLimitReport()
Dim shOptima As Worksheet, shCrc As Worksheet, shResult As Worksheet
Dim aRng, bRng As Range
Dim Fnd As Range
Dim ListObject As ListObject
Set shOptima = Sheets("Optima Blue")
Set shCrc = Sheets("CRC Limit Consolidated")
Set shResult = Sheets("Result Limit")
bLastRow = shResult.Cells(Rows.Count, "A").End(xlUp).Row
aLastRow = shCrc.Cells(Rows.Count, "A").End(xlUp).Row
Set aRng = shCrc.Range("A2:A" & aLastRow & "") '127
Set bRng = shResult.Range("A2:A" & bLastRow & "") '71
For Each aCell In aRng
For Each bcell In bRng
If aCell Is Nothing Or bcell Is Nothing Then
ElseIf aCell.Text = bcell.Text Then
bcell.Offset(0, 2).Formula = "='CRC Limit Consolidated'!" & aCell.Offset(0, 1).Address & " "
Else
End If
Next bcell
Next aCell
shResult.Range("D2").Formula = "=IF(B2=0,IF(C2=0,0,abs(((B2-C2)/C2)*100)),abs(((C2-B2)/B2)*100))"
shResult.Range("D2").Copy
shResult.Range("D3:D" & bLastRow).PasteSpecial (xlPasteAll)
shResult.Range("D2:D" & bLastRow).NumberFormat = "#,##0"
shResult.Range("D2:D" & bLastRow).NumberFormat = "#,##0.00"
shResult.Activate
shResult.Range("A1") = "Facility ID"
shResult.Range("D1") = "Diff in percent"
shResult.Range("C1") = "CRC Limit"
shResult.Range("B2:D" & bLastRow & " ").NumberFormat = "#,##0"
shOptima.Range("E1:g1").Interior.ColorIndex = 35
Range("A1:G" & bLastRow).EntireColumn.AutoFit
Range("A2:D" & bLastRow).Sort key1:=Range("D2:D" & bLastRow), order1:=xlDescending, Header:=xlNo
Set ListObject = ActiveSheet.ListObjects.Add(xlSrcRange, Range("A1").CurrentRegion, , xlYes)
With ListObject
.Name = "Table4"
.TableStyle = "TableStyleMedium5"
End With
End Sub
Sub MakeResultUsageReport()
Dim shOptima As Worksheet, shCrc As Worksheet, shResult As Worksheet
Dim aRng, bRng As Range
Dim Fnd As Range
Dim ListObject As ListObject
Set shOptima = Sheets("Optima Green")
Set shCrc = Sheets("CRC Usage Consolidated")
Set shResult = Sheets("Result Usage")
bLastRow = shResult.Cells(Rows.Count, "A").End(xlUp).Row
aLastRow = shCrc.Cells(Rows.Count, "A").End(xlUp).Row
Set aRng = shCrc.Range("A2:A" & aLastRow & "")
Set bRng = shResult.Range("A2:A" & bLastRow & "")
For Each aCell In aRng
For Each bcell In bRng
If aCell Is Nothing Or bcell Is Nothing Then
ElseIf aCell.Text = bcell.Text Then
bcell.Offset(0, 2).Formula = "='CRC Usage Consolidated'!" & aCell.Offset(0, 1).Address & " "
Else
End If
Next bcell
Next aCell
shResult.Range("D2").Formula = "=IF(B2=0,IF(C2=0,0,abs(((B2-C2)/C2)*100)),abs(((C2-B2)/B2)*100))"
shResult.Range("D2").Copy
shResult.Range("D3:D" & bLastRow).PasteSpecial (xlPasteAll)
shResult.Range("D2:D" & bLastRow).NumberFormat = "#,##0"
shResult.Range("D2:D" & bLastRow).NumberFormat = "#,##0.00"
shResult.Activate
shResult.Range("A1") = "Facility ID"
shResult.Range("D1") = "Diff in percent"
shResult.Range("C1") = "CRC Usage"
shResult.Range("B2:D" & bLastRow & " ").NumberFormat = "#,##0"
shOptima.Range("E1:g1").Interior.ColorIndex = 35
Range("A1:G" & bLastRow).EntireColumn.AutoFit
Range("A2:D" & bLastRow).Sort key1:=Range("D2:D" & bLastRow), order1:=xlDescending, Header:=xlNo
Set ListObject = ActiveSheet.ListObjects.Add(xlSrcRange, Range("A1").CurrentRegion, , xlYes)
With ListObject
.Name = "Table4"
.TableStyle = "TableStyleMedium4"
End With
Application.ScreenUpdating = True
End Sub
Sub CloseBook(File As String)
Workbooks(File).Close savechanges:=False
End Sub
The script takes photos from the indicated folder and places them on slides according to the limit imposed by the user, e.g. 1000 photos / presentation. After that it has to create a new presentation.
It was working. But he stopped. Now I stop with a PowerPoint VBA error: "No currently active document window" at the moment when the script is to close the PowerPoint file and open a new one in which to continue saving the presentation.
Saving and closing a newly created presentation
Application.DisplayAlerts = ppAlertsNone
ActivePresentation.Save
ActiveWindow.Close <----- error here
Application.DisplayAlerts = ppAlertsAll
How to eliminate this error for the script to continue running?
All Code:
Option Explicit
Option Base 1
Option Private Module
Private il_plik As Integer
Private dostep_do_zdjec As Variant
Private tablica() As Variant
'Dla odwiedzających forum elektroda.pl - jeśli im się na coś przyda :)
Sub a_Dodaj_zdjecia_do_ppt()
Dim ogranicznik As Integer, roz_cznk_prw_str As Integer, roz_cznk_przezr As Integer
Dim plik As Integer, indeks As Integer, prezent As Integer, maks_zdj_prez As Integer
Dim maks_prez As Double
Dim cznk_prw_str As String, cznk_przezr As String, filterek As String, dostep_do_prez As String
Dim nazwa_prezent As String, nazwa_zdj As String, opis_zdj As String, prw_str As String
Dim opis_nagl_calej_prez As String, data_zdj As String, godzina_zdj As String
Dim info01 As String, info02 As String, info03 As String, info04 As String, info05 As String, info06 As String
Dim stempel_daty As Date
Dim il_zdj_w_prez As Variant
Dim nPrzezPrez As Object
'On Error GoTo koniec_blad
'-----------------------------------------------------------------------------------------------------------------------
'Ograniczenie maksymalnej ilości zdjęć na jedną prezentację
ogranicznik = 3000
'Ustawienia czcionki strony przewodniej - można sobie zmieniać poprzez tę zmienną
cznk_prw_str = "Arial" 'oryginalnie było "Calibri" - jednak ta czcionka z polskimi ą, ę, itd. nie wyświetlała się u mnie najlepiej
roz_cznk_prw_str = 36 '40
'Ustawienia czcionki strony przezrocza - można sobie zmieniać poprzez tę zmienną
cznk_przezr = "Arial" 'oryginalnie było "Calibri" - jednak ta czcionka z polskimi ą, ę, itd. nie wyświetlała się u mnie najlepiej
roz_cznk_przezr = 16 '18
'
'-----------------------------------------------------------------------------------------------------------------------
'
'Określenie opisu w nagłówku pojedynczej prezentacji - domyślne dla całej prezentacji
opis_nagl_calej_prez = Trim(InputBox("Proszę podać treść nagłówka dla przezroczy w prezentacji", "Treść nagłówka w prezentacji", "Zdjęcie wykonane w Kluczborku"))
'Określenie ilości zdjęć w pojedynczej prezentacji - domyślnie 500 szt.
il_zdj_w_prez = InputBox("Proszę podać ilość zdjęć na 1 prezentację", "Ilość zdjęć do umieszczenia w prezentacji", 500)
'Jeśli podano złą wartość
If il_zdj_w_prez = "" Or Not IsNumeric(Trim(il_zdj_w_prez)) Then
MsgBox "Podano złą wartość lub w ogóle jej nie podano" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
'Jeśli podano dobrą wartość, ale w 'granicach przyzwoitości' typu Integer dla zmiennej 'ogranicznik'
il_zdj_w_prez = Abs(CInt(Trim(il_zdj_w_prez)))
If il_zdj_w_prez > ogranicznik Then
MsgBox "Przekroczono wartość graniczną" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
'Określenie dostępu do katalogu ze zdjęciami
With Application.FileDialog(msoFileDialogFolderPicker)
filterek = ActivePresentation.Path
.AllowMultiSelect = False
.ButtonName = "Wybierz"
.InitialFileName = filterek
.Title = "Proszę wybrać katalog ze zdjęciami"
If .Show = -1 Then
dostep_do_zdjec = .SelectedItems(1)
Else
MsgBox "Nie podano dostępu do katalogu zdjęć" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
End With
'Określenie dostępu do katalogu zapisywanych prezentacji
With Application.FileDialog(msoFileDialogFolderPicker)
filterek = ActivePresentation.Path
.AllowMultiSelect = False
.ButtonName = "Wybierz"
.InitialFileName = filterek
.Title = "Proszę podać miejsce zapisu prezentacji"
If .Show = -1 Then
dostep_do_prez = .SelectedItems(1)
Else
MsgBox "Nie podano dostępu do katalogu prezentacji" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
End With
'Początek obróbki
MsgBox "Teraz rozpocznie się pobieranie nazw zdjęć" & vbCrLf & vbCrLf & "Może to trochę potrwać, zależnie od ich ilości", vbOKOnly, "Uwaga !"
'Pozyskanie nazw plików oraz ich posortowanie, wzrastająco, według daty utworzenia
'Pobrane zostaną tylko zdjęcia z rozszerzeniami: '*.bmp', '*.gif', '*.jpg', '*.jpeg', '*.png'
Call b_Lista_plikow_w_katalogu(dostep_do_zdjec)
Call c_sortowanie_babelkowe(tablica)
'Korekta liczby zdjęć w prezentacji, jeśli zadeklarowano większą ich ilość niż liczba wszystkich zdjęć do obróbki
If il_zdj_w_prez > il_plik Then il_zdj_w_prez = il_plik
'Określenie ilości prezentacji, jaka zostanie utworzona,
'w oparciu o ogólną ilość zdjęć i tych, przypadających na pojedynczą prezentację
maks_prez = (il_plik / il_zdj_w_prez) - Fix(il_plik / il_zdj_w_prez)
If maks_prez > 0 And maks_prez < 0.5 Then
maks_prez = Round(il_plik / il_zdj_w_prez, 0) + 1
Else
maks_prez = Round(il_plik / il_zdj_w_prez, 0)
End If
'Wartości początkowe zmiennych wyznaczających zakres 'od-do' zdjęć w prezentacji
maks_zdj_prez = il_zdj_w_prez
plik = 1
For prezent = 1 To maks_prez
'Utworzenie nazwy nowopowstającej prezentacji
Select Case prezent
Case Is <= 9: nazwa_prezent = "Prez_" & "000" & prezent & ".ppt"
Case Is <= 99: nazwa_prezent = "Prez_" & "00" & prezent & ".ppt"
Case Is <= 999: nazwa_prezent = "Prez_" & "0" & prezent & ".ppt"
Case Else: nazwa_prezent = "Prez_" & "" & prezent & ".ppt"
End Select
'Utworzenie i zapisanie na dysku nowopowstającej prezentacji - okno prezentacji widoczne - 'msoTrue'
Presentations.Add(WithWindow:=msoTrue).SaveAs dostep_do_prez & "\" & nazwa_prezent
'Zmiana wielkości okna programu
'ActiveWindow.View.Zoom = 75
'Wartość początkowa zmiennej ustalającej położenie danego przezrocza w prezentacji
indeks = 0
For plik = plik To maks_zdj_prez
'Wydzielenie nazwy kopiowanego zdjęcia oraz daty i godziny jego utworzenia
nazwa_zdj = Mid(tablica(plik), InStr(1, tablica(plik), ";", 1) + 1, Len(tablica(plik)) - InStr(1, tablica(plik), ";", 1))
stempel_daty = CDate(Mid(tablica(plik), 1, InStr(1, tablica(plik), ";", 1) - 1))
data_zdj = Format(stempel_daty, "dd.mm.yyyy")
godzina_zdj = Format(stempel_daty, "hh:mm")
'Zmienna na ewentualny, dodatkowy opis w nagłówku przezrocza pobrany z tablicy - tu niewykorzystana
opis_zdj = "Opis dodatkowy"
'Dodanie nowego przezrocza
indeks = indeks + 1
ActivePresentation.Slides.Add Index:=indeks, Layout:=ppLayoutBlank
'Przypisanie obiektu przezrocza do zmiennej - skrócenie zapisu obiektu
Set nPrzezPrez = ActivePresentation.Slides(indeks)
'Wkopiowanie zdjęcia
'LinkToFile:=msoFalse - teoretycznie uniezależnia wkopiowane zdjęcie od 'zdjęcia macierzystego' pobranego z katalogu
nPrzezPrez.Shapes.AddPicture FileName:=dostep_do_zdjec & "\" & nazwa_zdj, LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, Left:=28, Top:=40, Width:=665, Height:=460
'Skalowanie wkopiowanego zdjęcia - zmianą liczby przy 'ScaleHeight' i 'ScaleWidth'
With nPrzezPrez.Shapes(1)
.LockAspectRatio = msoTrue
'.ScaleHeight 1.4, msoTrue, msoScaleFromMiddle 'msoScaleFromTopLeft 'msoScaleFromMiddle 'msoScaleFromBottomRight
'.ScaleWidth 1.4, msoTrue, msoScaleFromMiddle
.Width = 665
.Height = 460
End With
'Dodanie nagłówka
nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 9#, 703#, 62.38).TextFrame.TextRange.Text = "Zdjęcie nr " & Format(plik, "#,##0") & ": " & opis_nagl_calej_prez
'nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 9#, 703#, 62.38).TextFrame.TextRange.Text = "Zdjęcie nr " & Format(plik, "#,##0") & " (" & nazwa_zdj & ")"
'Inny układ opisu nagłówka - "Zdjęcie nr " & Format(plik, "#,##0") & ": " & nazwa_zdj & " - " & opis_zdj
'Formatowanie nagłówka
With nPrzezPrez.Shapes(2)
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoFalse
With .TextRange
.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Name = cznk_przezr: .Size = roz_cznk_przezr: .Bold = msoTrue
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.ForeColor.RGB = RGB(215, 228, 189)
.Solid
.Transparency = 0#
.Visible = msoTrue
End With
With .Line
.BackColor.RGB = RGB(255, 255, 255)
.ForeColor.RGB = RGB(79, 98, 40)
.Visible = msoTrue
End With
End With
'Dodanie stopki
nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 472#, 703#, 62.38).TextFrame.TextRange.Text = "DATA: " & data_zdj & ", godzina " & godzina_zdj
'Formatowanie stopki
With nPrzezPrez.Shapes(3)
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoFalse
With .TextRange
.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Name = cznk_przezr: .Size = roz_cznk_przezr: .Bold = msoTrue
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.ForeColor.RGB = RGB(215, 228, 189)
.Solid
.Transparency = 0#
.Visible = msoTrue
End With
With .Line
.BackColor.RGB = RGB(255, 255, 255)
.ForeColor.RGB = RGB(79, 98, 40)
.Visible = msoTrue
End With
End With
'Usunięcie dotychczasowych przypisań do zmiennych
Set nPrzezPrez = Nothing
nazwa_zdj = ""
stempel_daty = #1/1/1980#
data_zdj = ""
godzina_zdj = ""
opis_zdj = ""
'Co każde 1000 zdjęć 'odpuść' odrobinę na inne czynności - 'Niepraktyczne' w tym zadaniu
'If plik Mod 1000 = 0 Then DoEvents
Next plik
'Zmienna z tytułem prezentacji do strony przewodniej
prw_str = "PREZENTACJE" & vbCrLf & vbCrLf & "TYTUŁ" & vbCrLf & vbCrLf & "ILOŚĆ ZDJĘĆ: " & Format(indeks, "#,##0") & vbCrLf & vbCrLf & "OSTATNIA AKTUALIZACJA:" & vbCrLf & Format(Now(), "dd.mm.yyyy")
'Wstawienie strony przewodniej
ActivePresentation.Slides.Add Index:=1, Layout:=ppLayoutTitleOnly
'Sformatowanie strony przewodniej
With ActivePresentation.Slides(1).Shapes(1)
.Left = 54#
.Top = 167.75
.Width = 612.12
.Height = 115.62
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoTrue
With .TextRange
.ParagraphFormat.Alignment = ppAlignCenter
.Text = prw_str
With .Font
.Name = cznk_prw_str: .Size = roz_cznk_prw_str
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.Solid
.Transparency = 0#
.Visible = msoFalse
End With
With .Line
.Visible = msoFalse
End With
End With
'Zapis i zamknięcie nowoutworzonej prezentacji
Application.DisplayAlerts = ppAlertsNone
ActivePresentation.Save
' ActiveWindow.Close
ActivePresentation.Close
Application.DisplayAlerts = ppAlertsAll
'Czyszczenie zmiennej z tytułem prezentacji do strony przewodniej - na wszelki wypadek
prw_str = ""
'Jeśli przekroczono dopuszczalne wartości zmiennych, określone na początku, to korekta
'Można tu zastosować zmienną 'indeks'
maks_zdj_prez = il_zdj_w_prez + plik - 1
If maks_zdj_prez > il_plik Then maks_zdj_prez = il_plik
Next prezent
'Komunikat końcowy
info01 = "Procedura zakończona" & vbCrLf & vbCrLf
info02 = "Utworzono " & Format(maks_prez, "#,##0") & " prezentacje(-ę/-i) w: " & vbCrLf & vbCrLf
info03 = dostep_do_prez & vbCrLf & vbCrLf
info04 = "z " & Format(il_plik, "#,##0") & " zdjęć, po maksimum " & Format(il_zdj_w_prez, "#,##0") & " w każdej," & vbCrLf & vbCrLf
info05 = "pobranych z:" & vbCrLf & vbCrLf
info06 = dostep_do_zdjec
MsgBox info01 & info02 & info03 & info04 & info05 & info06, vbOKOnly, "Uwaga !"
Exit Sub
'Wykonaj jeśli w trakcie obróbki pojawił się jakiś błąd
koniec_blad:
On Error GoTo 0: On Error Resume Next
Application.DisplayAlerts = ppAlertsNone
With Presentations(nazwa_prezent)
.Saved = True: .Close
End With
Application.DisplayAlerts = ppAlertsAll
Set nPrzezPrez = Nothing
'Wykonaj po błędzie wyboru katalogu lub odwołaniu operacji ustalającej ilość zdjęć w prezentacji
koniec:
End
End Sub
Sub b_Lista_plikow_w_katalogu(dostep_do_zdjec As Variant)
Dim igt As Integer
Dim dlg As Integer, poz As Integer, licz As Integer
Dim rozsz_pliku As String
Dim ciag_prw As String, ciag_odtw As String, znak As String
Dim plik As Variant
Dim apli As Object, katalog As Object
On Error GoTo koniec
Set apli = CreateObject("Shell.Application")
Set katalog = apli.Namespace(dostep_do_zdjec)
'Inicjalizacja tablicy przechowującej dane o plikach zdjęć
ReDim tablica(1)
igt = 0
'Wpisanie informacji o plikach do tablicy
For Each plik In katalog.Items
'Wykonaj jeśli ma rozszerzenie
If InStrRev(plik, ".", -1, 1) <> 0 Then
rozsz_pliku = LCase(Mid(plik, InStrRev(plik, ".", -1, 1), 5))
'Pobierane będą dane tylko niektórych plików
If rozsz_pliku = ".jpg" Or rozsz_pliku = ".jpeg" Then
ciag_prw = CStr(katalog.GetDetailsOf(plik, 12))
'Dziwna wartość po wykonaniu <<katalog.GetDetailsOf(plik, 12)>>, tj. "?01-?03-?2017 ??19:21"
'Poniżej odtworzenie zapisu daty
dlg = Len(ciag_prw)
poz = 0
For licz = 1 To dlg
poz = poz + 1
znak = Mid(ciag_prw, poz, 1)
If Asc(znak) <> 63 Then ciag_odtw = ciag_odtw & znak
Next licz
If ciag_odtw = "" Then ciag_odtw = "01-01-1980 00:00"
igt = igt + 1
ReDim Preserve tablica(igt)
tablica(igt) = ciag_odtw & ";" & katalog.GetDetailsOf(plik, 0)
ciag_odtw = ""
Else
ciag_prw = CStr(katalog.GetDetailsOf(plik, 3))
If ciag_prw = "" Then ciag_prw = "01-01-1980 00:00"
igt = igt + 1
ReDim Preserve tablica(igt)
tablica(igt) = ciag_prw & ";" & katalog.GetDetailsOf(plik, 0)
ciag_prw = ""
End If
End If
Next plik
'Wstawia do zmiennej modułowej informację o ilości plików w tablicy
il_plik = igt
Set apli = Nothing
Set katalog = Nothing
Exit Sub
koniec:
Set apli = Nothing
Set katalog = Nothing
End Sub
Sub c_sortowanie_babelkowe(tablica As Variant)
Dim pocz As Integer, koniec As Integer
Dim i As Integer, j As Integer
Dim przech As Variant
On Error GoTo koniec
pocz = LBound(tablica)
koniec = UBound(tablica)
For i = pocz To koniec - 1
For j = i + 1 To koniec
If tablica(i) > tablica(j) Then
przech = tablica(j)
tablica(j) = tablica(i)
tablica(i) = przech
End If
Next j
Next i
Exit Sub
koniec:
End Sub
Edit://
I found a temporary solution to this. I fired this code, without the patch you wrote about on another computer, where I literally closed all windows in the window. Only the powerpoint was opened. The window with the script was on top. I didn't touch anything and the script worked fine on a large batch of photos (> 10k), creating a total of 11 presentation files. Can you explain to me as someone who is into programming and certainly VB programming does not know why this is happening and how to "remove" this problem?
At work I have excel 2013 and I have a for cicle that add new data to the series of a chart at every iteration.
It works flawlessly and at every iteration I can see the chart updating.
Now I tried the code on my home pc with excel 2016 and no matter what the chart won't update. I tried everything
dim chr as ChartObject
dim chrt as Chart
set chr = Sheet1.ChartObjects.Add
set chrt = chr.Chart
then I tried everything like
doevents
chr.refresh
sheet1.enablecalculation = true
application.screenupdating = true
chr.activate
Application.ontime Now + timeSerial(0,0,1), "wt"
sub wt
Application.wait + timeSerial(0,0,1)
end sub
anything you can think of .. it won't update
Any suggestion? thanks to everyone
EDIT: I found that it works if I add
Sheet1.ResetAllPageBreaks
at the end of each iteration, BUT it slows down the code too much
Sub risolutore()
Application.ScreenUpdating = True
' DICHIARAZIONE DELLE VARIABILI
Dim ws As Worksheet
Dim chr As ChartObject, chr2 As ChartObject
Dim rng As Range, rng2 As Range
Dim grafico As Chart, grafico2 As Chart
'''''''''''''''''''''''''''''''
' SHEET SETTING
Set ws = Foglio5
''''''''''''''''
For Each ch In ws.ChartObjects
ch.Delete
Next ch
'SETTAGGIO DELLE CELLE DI RIFERIMENTO'''''''''''
w_cells = ws.Range("B2:B9").Address
v_cell = ws.Range("B16").Address
s_cell = ws.Range(v_cell).Offset(1, 0).Address
m_cell = ws.Range(v_cell).Offset(2, 0).Address
sum_cell = ws.Range(v_cell).Offset(3, 0).Address
s_col = "F"
wci = "H"
wcf = "O"
nri = 14
ndati = 40
nrf = nri + ndati - 1
m_max = Application.WorksheetFunction.Max(ws.Range(w_cells).Offset(0, 1))
ws.Range(s_col & nri & ":" & wcf & nrf).ClearContents
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DoEvents
' CICLO RISOLUTORE E GRAFICI
For i = nri To nrf
ws.EnableCalculation = False
ws.EnableCalculation = True
' MIN VAR PORTFOLIO
If i = nri Then
' SETTAGGI DEL RISOLUTORE PER IL MIN VAR PORTFOLIO
obj = ws.Range(s_col & i).Offset(0, 1).Address
'reset dei parametri del solver
Application.Run "Solver.xlam!SolverReset"
'Decido la funzione da ottimizzare
Application.Run "Solver.xlam!SolverOk", v_cell, 2, 0, w_cells, 1, "GRG Nonlinear"
' vincolo di rendimento atteso
'Application.Run "Solver.xlam!SolverAdd", m_cell, 2, obj
' vincolo di peso maggiore di 0
Application.Run "Solver.xlam!SolverAdd", w_cells, 3, "0"
' vincolo di peso minore di 1
Application.Run "Solver.xlam!SolverAdd", w_cells, 1, "=1"
' vincolo di somma pesi uguale a 1
Application.Run "Solver.xlam!SolverAdd", sum_cell, 2, "=1"
Application.Run "Solver.xlam!SolverOptions", , , , , , , , , , , , False
' avvio il solver
Application.Run "Solver.xlam!SolverSolve", True
ws.Range(s_col & i).Value = ws.Range(s_cell).Value
ws.Range(s_col & i).Offset(0, 1).Value = ws.Range(m_cell).Value
ws.Range(s_col & i).NumberFormat = "0.000%"
ws.Range(s_col & i).Offset(0, 1).NumberFormat = "0.000%"
ws.Range(wci & i & ":" & wcf & i).Value = Application.WorksheetFunction.Transpose(ws.Range(w_cells).Value)
ws.Range(wci & i & ":" & wcf & i).NumberFormat = "0.00%"
' DETERMINO I VALORI DEI RENDIMENTI PER IL GRAFICO
m_min = ws.Range(m_cell).Value
max_min = m_max - m_min
Dim v() As Variant
ReDim v(1 To ndati)
v(1) = m_min
For K = LBound(v) + 1 To UBound(v)
v(K) = v(K - 1) + max_min / (ndati - 1)
Next K
ws.Range(s_col & nri).Offset(0, 1).Resize(UBound(v) - LBound(v) + 1).Value = Application.WorksheetFunction.Transpose(v)
ws.Range(s_col & nri).Offset(0, 1).Resize(UBound(v) - LBound(v) + 1).NumberFormat = "0.000%"
' SETTAGGI DEL PRIMO GRAFICO
Set rng = ws.Range("Q13:V25")
Set chr = ws.ChartObjects.Add(Left:=rng.Left, Width:=rng.Width, Top:=rng.Top, Height:=rng.Height)
Set grafico = chr.Chart
grafico.ChartType = xlXYScatterSmooth
grafico.SeriesCollection.NewSeries
grafico.SeriesCollection(1).XValues = ws.Range(s_col & nri).Offset(0, 0)
grafico.SeriesCollection(1).Values = ws.Range(s_col & nri).Offset(0, 1)
grafico.Axes(xlCategory).MinimumScale = ws.Range(s_col & nri).Offset(0, 0) * 0.8
grafico.Axes(xlCategory).TickLabels.Orientation = 35
grafico.Axes(xlValue).MinimumScale = m_min * 0.9
grafico.Axes(xlValue).MaximumScale = m_max * 1.1
grafico.Legend.Delete
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SETTAGGI DEL SECONDO GRAFICO
Set rng2 = ws.Range("Q26:V42")
Set chr2 = ws.ChartObjects.Add(Left:=rng2.Left, Width:=rng2.Width, Top:=rng2.Top, Height:=rng2.Height)
Set grafico2 = chr2.Chart
grafico2.ChartType = xlAreaStacked100
grafico2.HasTitle = False
grafico2.Legend.Position = xlLegendPositionBottom
grafico2.Axes(xlValue).MinimumScale = 0
For j = 1 To 8
grafico2.SeriesCollection.NewSeries
grafico2.SeriesCollection(j).XValues = ws.Range(s_col & nri & ":" & s_col & nri)
grafico2.SeriesCollection(j).Values = ws.Range(s_col & nri & ":" & s_col & nri).Offset(0, 2 + j - 1)
grafico2.SeriesCollection(j).Name = ws.Range(s_col & nri).Offset(-2, 2 + j - 1)
Next j
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' DETERMINO GLI ALTRI PORTAFOGLI EFFICIENTI
ElseIf i > nri Then
If i = nri + 1 Then
grafico.ChartType = xlXYScatterSmoothNoMarkers
End If
obj = ws.Range(s_col & i).Offset(0, 1).Address
'reset dei parametri del solver
Application.Run "Solver.xlam!SolverReset"
'Decido la funzione da ottimizzare
Application.Run "Solver.xlam!SolverOk", v_cell, 2, 0, w_cells, 1, "GRG Nonlinear"
' vincolo di rendimento atteso
Application.Run "Solver.xlam!SolverAdd", m_cell, 2, obj
' vincolo di peso maggiore di 0
Application.Run "Solver.xlam!SolverAdd", w_cells, 3, "0"
' vincolo di peso minore di 1
Application.Run "Solver.xlam!SolverAdd", w_cells, 1, "=1"
' vincolo di somma pesi uguale a 1
Application.Run "Solver.xlam!SolverAdd", sum_cell, 2, "=1"
Application.Run "Solver.xlam!SolverOptions", , , , , , , , , , , , False
' avvio il solver
Application.Run "Solver.xlam!SolverSolve", True
ws.Range(s_col & i).Value = ws.Range(s_cell).Value
ws.Range(s_col & i).NumberFormat = "0.000%"
ws.Range(wci & i & ":" & wcf & i).Value = Application.WorksheetFunction.Transpose(ws.Range(w_cells).Value)
ws.Range(wci & i & ":" & wcf & i).NumberFormat = "0.00%"
grafico.SeriesCollection(1).XValues = ws.Range(s_col & nri & ":" & s_col & i)
grafico.SeriesCollection(1).Values = ws.Range(s_col & nri & ":" & s_col & i).Offset(0, 1)
For j = 1 To 8
grafico2.SeriesCollection(j).XValues = ws.Range(s_col & nri & ":" & s_col & nrf)
grafico2.SeriesCollection(j).Values = ws.Range(s_col & nri & ":" & s_col & i).Offset(0, 2 + j - 1)
Next j
End If
Next i
Application.ScreenUpdating = True
MsgBox "Ottimizazione Completata", vbInformation
End Sub
Have you tried just changing the chart data?
I worked with charts and when i changed the data the chart changed instantly.
I'm trying to figure out a different method of running a piece of code.
Basically what my code is doing at the moment is, looping though column Q in the Global sheet, then looping though Combobox2, when it finds a match the entire rows get moved to the sheet reference in column 1 of the combobox.
Is it possible to use the Match function to achieve the same results and speed up the code??
This is currently the code I'm using, it does what I need it to do, but I cannot get error handling working for it. And it there are many rows of data to loop through it can take a long time!
Option 1:
Private Sub CommandButton6_Click()
Dim i As Long, j As Long, lastG As Long, strWS As String, rngCPY As Range
Dim StartTime As Double
Dim SecondsElapsed As Double
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
End With
StartTime = Timer
If Range("L9") = "" Then
MsgBox "You can't Split the Jobs at this stage. " & vbLf & vbLf & "Please create the form for the Sub-Contractor First." & vbLf & vbLf & "Please press Display Utilities to create form.", vbExclamation, "Invalid Operation"
Exit Sub
End If
If sheets("Global").Range("A3") = "" Then
MsgBox "The appears to be no application loaded." & vbLf & vbLf & "Please load" & " " & Range("C11") & " " & "App and Planet Info, then click button 2 and try again.", vbExclamation, "Invalid Operation"
Exit Sub
End If
On Error GoTo bm_Close_Out
' find last row
lastG = sheets("Global").Cells(Rows.Count, "Q").End(xlUp).row
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
If sheets("PAYMENT FORM").Range("L40") >= 1 Then
MsgBox "It appears you have already split the jobs, this operation can only be performed once.", vbExclamation, "Invalid Operation"
Exit Sub
Else
For j = 0 To Me.ComboBox2.ListCount - 1
currval = Me.ComboBox2.List(j, 0) ' value to match
For i = 3 To lastG
lookupVal = sheets("Global").Cells(i, "Q") ' value to find
If lookupVal = currval Then
Set rngCPY = sheets("Global").Cells(i, "Q").EntireRow
strWS = Me.ComboBox2.List(j, 1)
On Error GoTo bm_Need_Worksheet '<~~ if the worksheet in the next line does not exist, go make one
With Worksheets(strWS)
rngCPY.Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
End If
Next i
Next j
End If
Else
If sheets("PAYMENT FORM").Range("L35") >= 1 Then
MsgBox "It appears you have already split the jobs, this operation can only be performed once.", vbExclamation, "Invalid Operation"
Exit Sub
Else
For j = 0 To Me.ComboBox2.ListCount - 1
currval = Me.ComboBox2.List(j, 0) ' value to match
For i = 3 To lastG
lookupVal = sheets("Global").Cells(i, "Q") ' value to find
If lookupVal = currval Then
Set rngCPY = sheets("Global").Cells(i, "Q").EntireRow
strWS = Me.ComboBox2.List(j, 1)
On Error GoTo bm_Need_Worksheet '<~~ if the worksheet in the next line does not exist, go make one
With Worksheets(strWS)
rngCPY.Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
End If
Next i
Next j
End If
End If
GoTo bm_Close_Out
bm_Need_Worksheet:
On Error GoTo 0
With Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsTemplate As Worksheet: Set wsTemplate = wb.sheets("Template")
Dim wsPayment As Worksheet: Set wsPayment = wb.sheets("Payment Form")
Dim wsNew As Worksheet
Dim lastRow2 As Long
Dim Contract As String: Contract = sheets("Payment Form").Range("C9").value
Dim SpacePos As Integer: SpacePos = InStr(Contract, "- ")
Dim Name As String: Name = Left(Contract, SpacePos)
Dim Name2 As String: Name2 = Right(Contract, Len(Contract) - Len(Name))
Dim NewName As String: NewName = strWS
Dim CCName As Variant: CCName = Me.ComboBox2.List(j, 2)
Dim LastRow As Long: LastRow = wsPayment.Range("U36:U53").End(xlDown).row
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
lastRow2 = wsPayment.Range("A23:A39").End(xlDown).row
Else
lastRow2 = wsPayment.Range("A18:A34").End(xlDown).row
End If
wsTemplate.Visible = True
wsTemplate.Copy before:=sheets("Details"): Set wsNew = ActiveSheet
wsTemplate.Visible = False
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsPayment
For Each cell In .Range("A23:A39")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("C9").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " -" & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
Else
With wsPayment
For Each cell In .Range("A18:A34")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("C9").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " -" & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
End If
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A23:A39").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
Else
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A18:A34").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
End If
wsPayment.Activate
With wsPayment
.Range("J" & lastRow2 + 1).value = 0
.Range("L" & lastRow2 + 1).Formula = "=N" & lastRow2 + 1 & "-J" & lastRow2 + 1 & ""
.Range("N" & lastRow2 + 1).Formula = "='" & NewName & "'!L20"
.Range("U" & LastRow + 1).value = NewName & ": "
.Range("V" & LastRow + 1).Formula = "='" & NewName & "'!I21"
.Range("W" & LastRow + 1).Formula = "='" & NewName & "'!I23"
.Range("X" & LastRow + 1).Formula = "='" & NewName & "'!K21"
End With
End With
On Error GoTo bm_Close_Out
Resume
bm_Close_Out:
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = True
End With
End Sub
Option 2:
Private Sub CommandButton1_Click()
Dim j As Long, strWS As String, rngCPY As Range, FirstAddress As String, sSheetsWithData As String
Dim sSheetsWithoutData As String, lSheetRowsCopied As Long, lAllRowsCopied As Long, bFound As Boolean, sOutput As String
Dim StartTime As Double
Dim SecondsElapsed As Double
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
.EnableEvents = False
End With
StartTime = Timer
On Error GoTo bm_Close_Out
For j = 0 To UserForm2.ComboBox2.ListCount - 1
bFound = False
currval = UserForm2.ComboBox2.List(j, 0) ' value to match
With sheets("Global")
Set rngCPY = sheets("Global").Range("Q:Q").Find(currval, LookIn:=xlValues)
If Not rngCPY Is Nothing Then
bFound = True
lSheetRowsCopied = 0
FirstAddress = rngCPY.Address
Do
lSheetRowsCopied = lSheetRowsCopied + 1
strWS = UserForm2.ComboBox2.List(j, 1)
On Error GoTo bm_Need_Worksheet
With Worksheets(strWS)
rngCPY.EntireRow.Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
Set rngCPY = sheets("Global").Range("Q:Q").FindNext(rngCPY)
Loop Until rngCPY Is Nothing Or rngCPY.Address = FirstAddress
Else
bFound = False
End If
If bFound Then
sSheetsWithData = sSheetsWithData & " " & strWS & " (" & lSheetRowsCopied & ")" & vbLf
lAllRowsCopied = lAllRowsCopied + lSheetRowsCopied
End If
End With
Next j
bm_Need_Worksheet:
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsTemplate As Worksheet: Set wsTemplate = wb.sheets("Template")
Dim wsPayment As Worksheet: Set wsPayment = wb.sheets("Payment Form")
Dim wsNew As Worksheet
Dim lastRow2 As Long
Dim Contract As String: Contract = sheets("Payment Form").Range("C9").value
Dim SpacePos As Integer: SpacePos = InStr(Contract, "- ")
Dim Name As String: Name = Left(Contract, SpacePos)
Dim Name2 As String: Name2 = Right(Contract, Len(Contract) - Len(Name))
Dim NewName As String: NewName = strWS
Dim CCName As Variant: CCName = UserForm2.ComboBox2.List(j, 2)
Dim LastRow As Long: LastRow = wsPayment.Range("U36:U53").End(xlDown).row
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
lastRow2 = wsPayment.Range("A23:A39").End(xlDown).row
Else
lastRow2 = wsPayment.Range("A18:A34").End(xlDown).row
End If
wsTemplate.Visible = True
wsTemplate.Copy before:=sheets("Details"): Set wsNew = ActiveSheet
wsTemplate.Visible = False
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsPayment
For Each cell In .Range("A23:A39")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("C9").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " -" & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
Else
With wsPayment
For Each cell In .Range("A18:A34")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("C9").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " -" & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
End If
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A23:A39").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
Else
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A18:A34").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
End If
wsPayment.Activate
With wsPayment
.Range("J" & lastRow2 + 1).value = 0
.Range("L" & lastRow2 + 1).Formula = "=N" & lastRow2 + 1 & "-J" & lastRow2 + 1 & ""
.Range("N" & lastRow2 + 1).Formula = "='" & NewName & "'!L20"
.Range("U" & LastRow + 1).value = NewName & ": "
.Range("V" & LastRow + 1).Formula = "='" & NewName & "'!I21"
.Range("W" & LastRow + 1).Formula = "='" & NewName & "'!I23"
.Range("X" & LastRow + 1).Formula = "='" & NewName & "'!K21"
End With
On Error GoTo bm_Close_Out
Resume
bm_Close_Out:
If sSheetsWithData <> vbNullString Then
sOutput = "# of rows copied to sheets:" & vbLf & vbLf & sSheetsWithData & vbLf & _
"Total rows copied = " & lAllRowsCopied & vbLf & vbLf
Else
sOutput = "No sheets contained data to be copied" & vbLf & vbLf
End If
If sSheetsWithoutData <> vbNullString Then
sOutput = sOutput & "Sheets with no rows copied:" & vbLf & vbLf & sSheetsWithoutData
Else
sOutput = sOutput & "All sheets had data that was copied."
End If
If sOutput <> vbNullString Then MsgBox sOutput, , "Copy Report"
Set rngCPY = Nothing
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = True
.EnableEvents = True
End With
End Sub
OK... It's more like a try than an answer. pls check if that is working and if it is faster.
Use this macro only with a copy of your workbook!
Private Sub CommandButton2_Click()
Dim i As Long, j As Long, k As Long, strWS As String, rngCPY As Range
Dim noFind As Variant: noFind = UserForm2.ComboBox2.List '<~~~ get missed items
With Application: .ScreenUpdating = False: .EnableEvents = False: .CutCopyMode = False: End With
If Range("L9") = "" Then: MsgBox "You can't Split the Jobs at this stage. " & vbLf & vbLf & "Please create the form for the Sub-Contractor First." & vbLf & vbLf & "Please press Display Utilities to create form.", vbExclamation, "Invalid Operation": Exit Sub
Dim lastG As Long: lastG = Sheets("Global").Cells(Rows.Count, 17).End(xlUp).row
Dim cVat As Boolean: cVat = InStr(1, Sheets("Payment Form").Range("A20").Value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE")
If Sheets("PAYMENT FORM").Cells(35 - cVat * 5, 12) >= 1 Then: MsgBox "It appears you have already split the jobs, this operation can only be performed once.", vbExclamation, "Invalid Operation": Exit Sub
'~~~ acivate next line to sort (will speed up a lot)
'Sheets("Global").Range("A3:R" & Cells(Rows.Count, 17).End(xlUp).row).Sort cells(3,17), 1
For j = 0 To UserForm2.ComboBox2.ListCount - 1
noFind(j, 4) = 0
For i = 3 To lastG
If noFind(j, 0) = Sheets("Global").Cells(i, 17) Then
k = i
strWS = UserForm2.ComboBox2.List(j, 1)
On Error Resume Next
If Len(Worksheets(strWS).Name) = 0 Then
With ThisWorkbook
On Error GoTo 0
Dim nStr As String: With Sheets("Payment Form").Range("C9"): nStr = Right(.Value, Len(.Value) - Len(Left(.Value, InStr(.Value, "- ")))): End With
Dim CCName As Variant: CCName = UserForm2.ComboBox2.List(j, 2)
Dim lastRow As Long: lastRow = Sheets("Payment Form").Range("U36:U53").End(xlDown).row + 1
Dim strRng As String: strRng = Array("A18:A34", "A23:A39")(-1 * cVat)
Dim lastRow2 As Long: lastRow2 = Sheets("Payment Form").Range(strRng).End(xlDown).row + 1
Dim wsNew As Worksheet: .Sheets("Template").Copy .Sheets(.Sheets.Count): Set wsNew = .Sheets(.Sheets.Count): wsNew.Move .Sheets("Details")
With Sheets("Payment Form")
For Each cell In .Range(strRng)
If Len(cell) = 0 Then
If Sheets("Payment Form").Range("C9").Value = "Network" Then
cell.Offset.Value = strWS & " - " & nStr & ": " & CCName
Else
cell.Offset.Value = strWS & " -" & nStr & ": " & CCName
End If
Exit For
End If
Next cell
End With
With wsNew
.Visible = -1
.Name = strWS
.Cells(4, 4).Value = Sheets("Payment Form").Range(strRng).End(xlDown).Value
.Cells(6, 4).Value = Sheets("Payment Form").Cells(12, 12).Value
.Cells(8, 4).Value = Sheets("Payment Form").Cells(9, 3).Value
.Cells(10, 4).Value = Sheets("Payment Form").Cells(11, 3).Value
End With
With .Sheets("Payment Form")
.Activate
.Cells(lastRow2, 10).Value = 0
.Cells(lastRow2, 12).Formula = "=N" & lastRow2 & "-J" & lastRow2 & ""
.Cells(lastRow2, 14).Formula = "='" & strWS & "'!L20"
.Cells(lastRow, 21).Value = strWS & ": "
.Cells(lastRow, 22).Formula = "='" & strWS & "'!I21"
.Cells(lastRow, 23).Formula = "='" & strWS & "'!I23"
.Cells(lastRow, 24).Formula = "='" & strWS & "'!K21"
End With
End With
End If
On Error GoTo 0
While Sheets("Global").Cells(k + 1, 17).Value = noFind(j, 0) And k < lastG
k = k + 1
Wend
Set rngCPY = Sheets("Global").Range("Q" & i & ":Q" & k).EntireRow
With Worksheets(strWS)
rngCPY.Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
noFind(j, 4) = noFind(j, 4) + k - i + 1
i = k
End If
Next i
Next j
With Application: .ScreenUpdating = True: .EnableEvents = True: .CutCopyMode = True: End With
'noFind(x, y) > x = item / y: 0 = name / y: 4 = counter
noFind(0, 0) = noFind(0, 0) & " " & noFind(0, 4) & " times copied"
For i = 1 To UBound(noFind)
noFind(0, 0) = noFind(0, 0) & vbLf & noFind(i, 0) & " " & noFind(i, 4) & " times copied"
Next
MsgBox noFind(0, 0)
End Sub
At first: you may add some empty lines for better understanding...
Most parts are just shortened by view (they still do tha same).
When using the sort option, it will copy/paste all rows for each keyword in one step. That not only sounds faster... However, you may resort at the end again
Pls check if it works with your real workbook (copy of it, but with all data inside). I haven't done any "indeep speed tuning".
Here is a small section of your code that replace the loop through each cell in Global!Q3:Q*<last_row>* with the VBA version of the MATCH function.
Dim rw As Long, rngGQs As Range '<~~ put this closer to the top with the other variable declarations
' find last row
'lastG = Sheets("Global").Cells(Rows.Count, "Q").End(xlUp).Row '<~~old way
With Sheets("Global") '<~~new way
Set rngGQs = .Range(Cells(3, "Q"), .Cells(Rows.Count, "Q").End(xlUp)) '< ~~ all of the cells to look at
End With
If InStr(1, Sheets("Payment Form").Range("A20").Value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
If Sheets("PAYMENT FORM").Range("L40") >= 1 Then
MsgBox "It appears you have already split the jobs, this operation can only be performed once.", vbExclamation, "Invalid Operation"
Exit Sub
Else
For j = 0 To Me.ComboBox2.ListCount - 1
currval = Me.ComboBox2.List(j, 0) ' value to match
'For i = 3 To lastG '<~~old way
'lookupVal = Sheets("Global").Cells(i, "Q") ' value to find
'If lookupVal = currval Then
If Not IsError(Application.Match(currval, rngGQs, 0)) Then '<~~new way
rw = Application.Match(currval, rngGQs, 0)
Set rngCPY = Sheets("Global").Cells(rw, "Q").EntireRow
'all the rest here
When you get this to a satisfactory working order, it will be a prime candidate for suggestions at Code Review (Excel).
You could try something like this. The Range.Find-Method basically looks through the given range for a value which you can specify. If a match is found, the cell in which the match is found, can then be stored.
You can then also use .FindNext to find the next occurrence of that value, if needed.
For j = 0 To Me.ComboBox2.ListCount - 1
currval = Me.ComboBox2.List(j, 0) ' value to match
Set rngCPY = sheets("Global").Range("Q:Q").Find(currval, LookIn:=xlValues)
Do While Not rngCPY Is Nothing
strWs = Me.ComboBox2.List(j, 1)
rngCPY.EntireRow.Copy
With Worksheets(strWS)
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
Set rngCPY = sheets("Global").Range("Q:Q").FindNext(rngCPY)
Loop
Next j
I've seen numerous questions on the issue but none of the solutions fit my situation (I think) so any help is appreciated. I receive the error when setting the value of the LR integer variable. As with many others having this issue, it only fails the second time the subroutine is run.
Sub SaveEmailAttachments()
' Creates each variable to be used
Dim xlApp As Excel.Application, xlWB As Excel.Workbook, xlAtt As Excel.Workbook
Dim olItem As Outlook.MailItem
Dim LR As Integer, NR As Integer, j As Integer, intDir As Integer, random As Integer
' Path to the HWB Master template to be used
Const strPath As String = "C:\Users\dkirksey\Documents\SOF\SOF Station HWB Master w Macro.xlsm"
' If no emails are selected, present an error and exit
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
' Creates a new Excel application
On Error Resume Next
Set xlApp = New Excel.Application
xlApp.Visible = False
'Opens the Excel workbook
On Error GoTo 0
Set xlWB = xlApp.Workbooks.Open(strPath)
'Creates a new directory to store today's information
intDir = (fIsFileDIR("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy"), vbDirectory))
If intDir = 0 Then
MkDir ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy"))
MkDir ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & "\HWBs")
'Process each selected email
For Each olItem In Application.ActiveExplorer.Selection
j = j + 1
For cnt = 1 To olItem.Attachments.Count
If Right(olItem.Attachments(1).FileName, 4) = "xlsx" Or Right(olItem.Attachments(1).FileName, 3) = "xls" Or Right(olItem.Attachments(1).FileName, 4) = "xlsm" Then
olItem.Attachments(cnt).SaveAsFile ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & "\HWBs\" _
& Format(Now, "mmddyy") & " " & j & olItem.Attachments(cnt).DisplayName)
Set xlAtt = xlApp.Workbooks.Open("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & "\HWBs\" _
& Format(Now, "mmddyy") & " " & j & olItem.Attachments(cnt).DisplayName)
xlAtt.Activate
If xlAtt.ActiveSheet.Range("A3").Value = "HWB" And xlAtt.ActiveSheet.Range("B3").Value = "Instruction (optional)" And xlAtt.ActiveSheet.Range("C3").Value = "Route (optional)" Then
LR = xlAtt.ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
xlAtt.ActiveSheet.Range("A4:C4" & LR).Select
Selection.Copy
xlWB.Activate
xlWB.ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1).Select
Selection.PasteSpecial xlPasteValues
xlWB.ActiveSheet.Cells(1, 1).Activate
End If
xlApp.DisplayAlerts = False
xlAtt.Close SaveChanges:=False
Else
olItem.Categories = "Purple Category"
End If
Next
Next olItem
j = 4
LR = xlWB.ActiveSheet.UsedRange.Rows.Count
Do Until j > LR
If IsNumeric(Cells(j, 1)) = False Then
Cells(j, 1).EntireRow.Delete
LR = LR - 1
ElseIf Cells(j, 1).Value = "" Then
Cells(j, 1).EntireRow.Delete
LR = LR - 1
Else
j = j + 1
End If
Loop
xlWB.SaveAs ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & "\" & Format(Now, "mmddyy") & " Complete HWB List")
Else
ans = MsgBox("You have already run SOF today, would you like to continue anyway?", vbYesNo)
If ans = vbYes Then
random = Int((9999 - 100 + 1) * Rnd + 100)
MkDir ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & random)
MkDir ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & random & "\HWBs")
MsgBox "Your new folder is titled " & Format(Now, "mmddyy") & random & ", it is located in the Documents\SOF\HWB Files directory"
'Process each selected email
For Each olItem In Application.ActiveExplorer.Selection
j = j + 1
For cnt = 1 To olItem.Attachments.Count
If Right(olItem.Attachments(1).FileName, 4) = "xlsx" Or Right(olItem.Attachments(1).FileName, 3) = "xls" Or Right(olItem.Attachments(1).FileName, 4) = "xlsm" Then
olItem.Attachments(cnt).SaveAsFile ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & random & "\HWBs\" _
& Format(Now, "mmddyy") & " " & j & olItem.Attachments(cnt).DisplayName)
Set xlAtt = xlApp.Workbooks.Open("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & random & "\HWBs\" _
& Format(Now, "mmddyy") & " " & j & olItem.Attachments(cnt).DisplayName)
xlAtt.Activate
If xlAtt.ActiveSheet.Range("A3").Value = "HWB" And xlAtt.ActiveSheet.Range("B3").Value = "Instruction (optional)" And xlAtt.ActiveSheet.Range("C3").Value = "Route (optional)" Then
LR = xlAtt.ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
xlAtt.ActiveSheet.Range("A4:C4" & LR).Select
Selection.Copy
xlWB.Activate
xlWB.ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1).Select
Selection.PasteSpecial xlPasteValues
xlWB.ActiveSheet.Cells(1, 1).Activate
End If
xlApp.DisplayAlerts = False
xlAtt.Close SaveChanges:=False
Else
olItem.Categories = "Purple Category"
End If
Next
Next olItem
j = 4
LR = xlWB.ActiveSheet.UsedRange.Rows.Count
Do Until j > LR
If IsNumeric(Cells(j, 1)) = False Then
Cells(j, 1).EntireRow.Delete
LR = LR - 1
ElseIf Cells(j, 1).Value = "" Then
Cells(j, 1).EntireRow.Delete
LR = LR - 1
Else
j = j + 1
End If
Loop
xlWB.SaveAs ("C:\Users\dkirksey\Documents\SOF\HWB Files\" & Format(Now, "mmddyy") & random & "\" & Format(Now, "mmddyy") & " Complete HWB List")
Else
xlWB.Close
xlApp.DisplayAlerts = True
xlApp.Quit
Exit Sub
End If
End If
xlWB.Close
xlApp.DisplayAlerts = True
xlApp.Quit
MsgBox "Well played !"
End Sub
I'm a rookie with VBA so excuse any redundant or just plain idiotic coding methods you notice.
The subroutine works perfectly the first time it is run, just not the second. Please help.
Thank you.