Excel VBA Macro - Out of Memory Error - vba

I am having trouble when running a macro whereby I get an error, usually at the end, stating that it "Out of memory".
I've looked over a number of posts and followed recommendations to clear any variables and ensure that the code is "cleaner". However, the error still persists.
I have included the code below, any feedback would be greatly appreciated.
A summary of the purpose:
User clicks a button in a template (which is where the code resides)
Macro 1 cleans up the data that the user pastes into a template page.
A userform will appear after macro 1 which the user must input some data - customer name, contract numbers, etc.
Macro 2 runs when the userform button is submitted which creates a new workbook containing all the data from the template (formatted in macro1) and the data from the form.
It then formats the data for printing with a logo, etc.
Macro 1
Private Sub ContractsClean()
Application.Visible = True
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.CutCopyMode = False
Sheets("Paste").Name = "Data"
Sheets("Data").Columns("A:B").EntireColumn.Delete
Dim x As Long, lastrow As Long
lastrow = Sheets("Data").Cells(Rows.Count, "A").End(xlUp).Row
'Clean the codes
For x = lastrow To 2 Step -1
If Len(Sheets("Data").Cells(x, 1)) > 9 Then
Sheets("Data").Cells(x, 1).Value = Right(Sheets("Data").Cells(x, 1).Value, 9)
End If
Next x
'Add the leading zero
Sheets("Data").Select
Range("A:A").Select
Dim Rng As Range
Dim bChanged As Boolean
Dim icol As Long
Dim sString As String
Dim iWSs As Long
iWSs = Workbooks.Count
If iWSs >= 1 Then
icol = Selection.Column
lastrow = Cells(Rows.Count, icol).End(xlUp).Row
For Each Rng In Selection
If TypeName(Rng.Value) = "Double" Then
If Left(Rng.Value, 1) = "9" Then
Rng = "'0" & Rng.Value
bChanged = True
End If
End If
If TypeName(Rng.Value) = "String" Then
If Left(Rng.Value, 3) = "09-" Then
sString = Rng.Value
sString = "'" & Replace(sString, "-", "")
Rng.Value = sString
bChanged = True
End If
End If
If Rng.Errors(xlNumberAsText).Value = True And bChanged = True Then Rng.Errors(xlNumberAsText).Ignore = True
If Rng.Row = lastrow Then Exit For
Next Rng
End If
If iWSs >= 1 Then
icol = Selection.Column
lastrow = Cells(Rows.Count, icol).End(xlUp).Row
For Each Rng In Selection
If TypeName(Rng.Value) = "Double" Then
If Left(Rng.Value, 1) = "8" Then
Rng = "'0" & Rng.Value
bChanged = True
End If
End If
If TypeName(Rng.Value) = "String" Then
If Left(Rng.Value, 3) = "08-" Then
sString = Rng.Value
sString = "'" & Replace(sString, "-", "")
Rng.Value = sString
bChanged = True
End If
End If
If Rng.Errors(xlNumberAsText).Value = True And bChanged = True Then Rng.Errors(xlNumberAsText).Ignore = True
If Rng.Row = lastrow Then Exit For
Next Rng
End If
Rng = Empty
bChanged = Empty
icol = Empty
sString = Empty
iWSs = Empty
Sheets("Data").Columns("B").EntireColumn.Delete
Sheets("Data").Range("C1").Value = "Quantity"
Sheets("Data").Columns("D").EntireColumn.Delete
Sheets("Data").Columns("E").EntireColumn.Delete
Sheets("Data").Range("E:F").NumberFormat = "dd/mm/yyyy"
Dim ws As Worksheet
Set ws = Sheets("Data")
ws.Range("A:B").Locked = False
ws.Range("C:D").Locked = True
ws.Range("E:F").Locked = False
ws.Protect DrawingObjects:=True, Contents:=True, Scenarios:= _
True, AllowDeletingRows:=True, AllowFormattingCells:=True, AllowFiltering:=True, AllowInsertingRows:=True, Password:="Sanchez7"
'Completion message box
Dim Answer As String
Dim MyNote As String
'Place your text here
MyNote = "Cleanse complete. Do you want to create a local price agreement?"
'Display MessageBox
Answer = MsgBox(MyNote, vbQuestion + vbYesNo, "Action")
If Answer = vbNo Then
'Code for No button Press
Else
'Code for Yes button Press
ProposalForm.Show
End If
Answer = Empty
MyNote = Empty
lastrow = Empty
End Sub
Form Code
Private Sub CommandButton1_Click()
Dim sBuyGroup As String, sLPA As String, sRep As String, sStart As Date, sEnd As Date, sCurrency As String
Dim bExit As Boolean, sSort As String
sBuyGroup = txt_BuyGroup.Text
sLPA = txt_LPA.Text
sRep = txt_Rep.Text
sStart = txt_Start.Text
sEnd = txt_End.Text
sCurrency = ComboBox1.Value
If sBuyGroup = "" Then
bExit = True
MsgBox ("The account number cannot be blank")
End If
If sLPA = "" And bExit = False Then
bExit = True
MsgBox ("The carriage option cannot be blank")
End If
If sRep = "" And bExit = False Then
bExit = True
MsgBox ("The discount option cannot be blank")
End If
If bExit = False Then
Call CreateProposal(sBuyGroup, sLPA, sRep, sStart, sEnd, sCurrency)
Unload Me
Else
End If
sBuyGroup = Empty
sLPA = Empty
sRep = Empty
sStart = Empty
sEnd = Empty
sCurrency = Empty
End Sub
Macro 3 (which I believe is what causes the error)
Sub CreateProposal(sBuyGroup As String, sLPA As String, sRep As String, sStart As Date, sEnd As Date, sCurrency As String)
Dim picLogo As Picture
Set picLogo = Sheets("Info").Pictures("PH_LOGO")
'Copy data from original workbook
Dim exApp As Excel.Application
Set exApp = GetExcelObject()
exApp.Visible = True
Dim OGWB As Workbook
Set OGWB = ActiveWorkbook
OGWB.Sheets("Data").Range("A1:F15000").Copy
Dim wbProposal As Workbook
Set wbProposal = exApp.Workbooks.Add
wbProposal.Activate
wbProposal.Sheets("Sheet1").Range("A1").PasteSpecial xlPasteValues
wbProposal.Sheets("Sheet1").Name = "Raw"
exApp.CutCopyMode = False
exApp.Application.ScreenUpdating = False
'Copy the logo so we can close original workbook
wbProposal.Sheets.Add
wbProposal.Sheets("Sheet2").Name = "LPA"
OGWB.Sheets("Info").Pictures("PH_LOGO").Cut
wbProposal.Sheets("LPA").Paste
Selection.Name = "PH_LOGO"
wbProposal.Sheets("LPA").Pictures("PH_LOGO").Left = 20
wbProposal.Sheets("LPA").Pictures("PH_LOGO").Top = 13
'wbProposal.Sheets("LPA").Pictures("PH_LOGO").Width = Application.CentimetersToPoints(5.51)
'wbProposal.Sheets("LPA").Pictures("PH_LOGO").Height = Application.CentimetersToPoints(1.64)
wbProposal.Sheets("LPA").Range("A1").Select
Set picLogo = Nothing
exApp.CutCopyMode = False
wbProposal.Activate
wbProposal.Sheets("LPA").Select
'Set BG to all white
With wbProposal.Sheets("LPA").Cells.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'Add contact header
wbProposal.Sheets("LPA").Range("D2").Value = "performancehealth.co.uk"
wbProposal.Sheets("LPA").Range("D3").Value = "Main: +44 (0) 3448 730 035"
wbProposal.Sheets("LPA").Range("D4").Value = "Fax: +44 (0) 1623 557 769"
wbProposal.Sheets("LPA").Range("G2").Value = "Nunn Brook Road, Huthwaite,"
wbProposal.Sheets("LPA").Range("G3").Value = "Sutton-in-Ashfield"
wbProposal.Sheets("LPA").Range("G4").Value = "Nottinghamshire, NG17 2HU, UK"
With wbProposal.Sheets("LPA").Range("D2").Font
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0
.Bold = True
End With
With wbProposal.Sheets("LPA").Range("D3:D4,G2:G4").Font
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0.499984740745262
End With
wbProposal.Sheets("LPA").Range("G6").Value = "Local Price Agreement"
With wbProposal.Sheets("LPA").Range("G6").Font
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0
.Bold = True
.Size = 14
End With
'Arrange Column widths
wbProposal.Sheets("LPA").Columns("A").ColumnWidth = 2.5
wbProposal.Sheets("LPA").Columns("B").ColumnWidth = 13
wbProposal.Sheets("LPA").Range("B14").Value = "Item Code"
wbProposal.Sheets("LPA").Columns("C").ColumnWidth = 41.5
wbProposal.Sheets("LPA").Range("C14").Value = "Item Description"
wbProposal.Sheets("LPA").Columns("D:F").ColumnWidth = 12
wbProposal.Sheets("LPA").Range("D14").Value = "Sale UOM"
wbProposal.Sheets("LPA").Range("E14").Value = "Min Qty"
wbProposal.Sheets("LPA").Range("F14").Value = "Rate"
wbProposal.Sheets("LPA").Columns("G:H").ColumnWidth = 13.5
wbProposal.Sheets("LPA").Range("G14").Value = "Start Date"
wbProposal.Sheets("LPA").Range("H14").Value = "Expiry Date"
wbProposal.Sheets("LPA").Range("B14:H14").Font.Bold = True
With wbProposal.Sheets("LPA").Range("B14:H14").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -4.99893185216834E-02
.PatternTintAndShade = 0
End With
'Fill out details from form
wbProposal.Sheets("LPA").Range("B8").Value = "Buying Group:"
wbProposal.Sheets("LPA").Range("B10").Value = "Sales Rep:"
wbProposal.Sheets("LPA").Range("B11").Value = "Currency:"
wbProposal.Sheets("LPA").Range("E8").Value = "LPA Number:"
wbProposal.Sheets("LPA").Range("E10").Value = "Start Date:"
wbProposal.Sheets("LPA").Range("E11").Value = "Expiry Date:"
wbProposal.Sheets("LPA").Range("B8:B11").Font.Bold = True
wbProposal.Sheets("LPA").Range("E8:E11").Font.Bold = True
wbProposal.Sheets("LPA").Range("C8").Value = sBuyGroup
wbProposal.Sheets("LPA").Range("C10").Value = sRep
wbProposal.Sheets("LPA").Range("C11").Value = sCurrency
wbProposal.Sheets("LPA").Range("F8").Value = sLPA
wbProposal.Sheets("LPA").Range("F10").Value = sStart
wbProposal.Sheets("LPA").Range("F11").Value = sEnd
sBuyGroup = Empty
sRep = Empty
sCurrency = Empty
sLPA = Empty
sStart = Empty
sEnd = Empty
'Import the list
Dim lastrow As Long
wbProposal.Sheets("Raw").Select
lastrow = wbProposal.Sheets("Raw").Cells(Rows.Count, "A").End(xlUp).Row
wbProposal.Sheets("Raw").Columns("C").Insert Shift:=xlToRight
wbProposal.Sheets("Raw").Range("F:G").NumberFormat = "dd/mm/yyyy"
wbProposal.Sheets("Raw").Range("E" & lastrow).NumberFormat = "£#,##0.00"
wbProposal.Sheets("Raw").Range("A2:G" & lastrow).Copy
wbProposal.Sheets("LPA").Select
wbProposal.Sheets("LPA").Range("B15").PasteSpecial xlPasteValuesAndNumberFormats
exApp.CutCopyMode = False
'Setup print area
lastrow = wbProposal.Sheets("LPA").Cells(Rows.Count, "B").End(xlUp).Row
wbProposal.Sheets("LPA").Range("F15:F" & lastrow).NumberFormat = "£#,##0.00"
wbProposal.Sheets("LPA").PageSetup.PrintArea = "$A$1:$H$" & lastrow
With wbProposal.Sheets("LPA").PageSetup
.PrintTitleRows = "$14:$14"
.PrintTitleColumns = ""
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 100
End With
'Redo the picture size (changes during column amendments
'wbProposal.Sheets("LPA").Pictures("PH_LOGO").Width = Application.CentimetersToPoints(5.51)
'wbProposal.Sheets("LPA").Pictures("PH_LOGO").Height = Application.CentimetersToPoints(1.64)
lastrow = Empty
exApp.DisplayAlerts = False
exApp.CutCopyMode = False
wbProposal.Sheets("LPA").Range("A1").Select
wbProposal.Sheets("Raw").Delete
exApp.DisplayAlerts = False
exApp.ScreenUpdating = True
OGWB.Close False
Set OGWB = Nothing
Set wbProposal = Nothing
Set exApp = Nothing
Application.Quit
End Sub
'-----------------------------------------------------------------------------
' Return an intance of Excel
' First tries to open an existing instance. If it fails, it will create an instance.
' If that fails too, then we return 'Nothing'
'-----------------------------------------------------------------------------
Public Function GetExcelObject() As Object
On Error Resume Next
Dim xlo As Object
' Try to get running instance of Excel
Set xlo = GetObject("Excel.Application")
If xlo Is Nothing Then
Set xlo = CreateObject("Excel.Application")
End If
Set GetExcelObject = xlo
End Function

Related

extracting the file and invoice from SAP

I have below code.
In first loop the excel file is extracted from the SAP - loop with variable a.
In the second loop (loop with variable k) the invoice is extracted from SAP (takes the order number from earlier extracted excel file).
The number of the order is taken from the excel file and paste to order in SAP.
Sometimes it happens, that order is either not taken from excel or not paste in SAP and the field for the order is empty.
This situation try to generates all the orders for the Controlling Area, which is very time-consuming (in fact it lasts hours).
I tried to add this line of code before the paste to the order, but of no result
Application.Wait Now + TimeValue("0:00:05")
Have you met this in your coding and could help with this?
extracting the excel file from SAP
Sub invoice_extr()
'##########################
'zapisuje pliki xlsx ordery
'##########################
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
Dim a As Double
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Range("b2:c" & last_row).Select
Selection.ClearContents
Dim path As String
path = Cells(2, 6)
For a = 2 To last_row
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK XLSX O TAKIEJ NAZWIE########
'###########################################################
Dim objFSO_november1 As Object
Dim objFolder_november1 As Object
Dim objFile_november1 As Object
Dim objFile1_november1 As Object
Dim aa_november1 As Integer
Dim bb_november1 As Integer
Set objFSO_november1 = CreateObject("Scripting.FileSystemObject")
Set objFolder_november1 = objFSO_november1.GetFolder(path)
bb_november1 = 0
For Each objFile1_november1 In objFolder_november1.Files
bb_november1 = bb_november1 + 1
Next objFile1_november1
Dim myArray_november1() As Variant
ReDim Preserve myArray_november1(bb_november1, 1)
aa_november1 = 0
For Each objFile_november1 In objFolder_november1.Files
myArray_november1(aa_november1, 1) = objFile_november1.name
aa_november1 = aa_november1 + 1
Next objFile_november1
Dim aa As Double
Dim zz As Double
zz = 0
For aa = 0 To aa_november1 - 1
Dim how_many As Double
how_many = Len(Cells(a, 1))
'MsgBox (Cells(a, 1))
'MsgBox (Left(myArray_november1(aa, 1), how_many))
'MsgBox (aa)
If (Cells(a, 1) * 1) = (Left(myArray_november1(aa, 1), how_many) * 1) Then
Cells(a, 2) = "Done"
zz = zz + 1
'MsgBox (zz)
End If
If zz <> 0 Then
GoTo line1
End If
Next aa
Erase myArray_november1
If zz <> 0 Then
GoTo line1
End If
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(a, 4)
Workbooks("Saving_invoice.xlsm").Activate
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(a, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
'On Error GoTo line1
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'################################################################
'#############WYBIERA LAYOUT /MACRO##############################
'################################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "BELNR"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").contextMenu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectContextMenuItem "&XXL"
session.findById("wnd[1]/usr/cmbG_LISTBOX").SetFocus
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "31"
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ctxtDY_PATH").Text = path
Dim name As String
name = Cells(a, 1) & ".xlsx"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").Text = name
session.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 10
session.findById("wnd[1]/tbar[0]/btn[0]").press
'line1:
Application.Wait Now + TimeValue("0:00:05")
If Not Dir(path & name, vbDirectory) = vbNullString Then
Dim wB1 As Workbook
Dim ws1 As Worksheet
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB1 = Workbooks.Open(path & name)
Set ws1 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name).Activate
Workbooks(name).Close
Cells(a, 2) = "Done"
Else
Cells(a, 2) = "Please, check the order!"
End If
'Dim wB1 As Workbook
'Dim ws1 As Worksheet
'
' With Application
' .DisplayAlerts = False
' .EnableEvents = False
' .ScreenUpdating = False
' End With
'
' Set wB1 = Workbooks.Open(path & name)
' Set ws1 = wB.Sheets(1)
'
' Application.Wait Now + TimeValue("0:00:05")
'Workbooks(name).Activate
'
'Workbooks(name).Close
'
'Cells(a, 2) = "Checked"
line1:
Erase myArray_november1
Next a
Call invoice_extr_2
End Sub
extracting the invoice from SAP
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
'####################################
'otwiera ordery i zapisuje faktury
'####################################
Workbooks("Saving_invoice.xlsm").Activate
Dim path As String
path = Cells(2, 6).Value
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Dim i As Double
For i = 2 To last_row
Dim name2 As String
name2 = Cells(i, 1) & ".xlsx"
Dim wB2 As Workbook
Dim ws2 As Worksheet
If Not Dir(path & name2, vbDirectory) = vbNullString Then
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB2 = Workbooks.Open(path & name2)
'Set ws2 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Else
GoTo line999999999
End If
Dim last_column As Integer
last_column = Cells(1, Columns.Count).End(xlToLeft).Column
'MsgBox (last_column)
Dim nr_kolumny As Long
nr_kolumny = Cells.Find(What:="Ref Document Number", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
If Cells(1, last_column) = "action" Then
Dim ostatnia_kolumna As Integer
ostatnia_kolumna = Cells.Find(What:="action", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
Else
ostatnia_kolumna = last_column + 1
End If
If Cells(1, last_column) = "action" Then
GoTo line2
Else
Cells(1, last_column + 1).Select
ActiveCell.FormulaR1C1 = "action"
End If
line2:
Dim k As Double
Dim last_row_document
last_row_document = Cells(Rows.Count, nr_kolumny).End(xlUp).Row - 2
For k = 2 To last_row_document
If Cells(k, ostatnia_kolumna) <> "Checked" Then
Workbooks("Saving_invoice").Activate
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(i, 4)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(i, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'#####################################################
'##############WYBIERA LAYOUT /MACRO##################
'#####################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
'######################################################
'############TUTAJ FILTROWANIE PO DOKUMENCIE###########
'######################################################
Workbooks(name2).Activate
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").setCurrentCell -1, "REFBN"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectColumn "REFBN"
session.findById("wnd[0]/tbar[1]/btn[29]").press
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = Cells(k, nr_kolumny)
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 8
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "REFBN"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK O TAKIEJ NAZWIE#############
'###########################################################
Dim objFSO_november As Object
Dim objFolder_november As Object
Dim objFile_november As Object
Dim objFile1_november As Object
Dim aa_november As Integer
Dim bb_november As Integer
Set objFSO_november = CreateObject("Scripting.FileSystemObject")
Set objFolder_november = objFSO_november.GetFolder(path)
bb_november = 0
For Each objFile1_november In objFolder_november.Files
bb_november = bb_november + 1
Next objFile1_november
Dim myArray_november() As Variant
ReDim Preserve myArray_november(bb_november, 1)
aa_november = 0
For Each objFile_november In objFolder_november.Files
myArray_november(aa_november, 1) = objFile_november.name
aa_november = aa_november + 1
Next objFile_november
Dim z As Double
Dim how_digits As Double
how_digits = Len(Cells(k, nr_kolumny))
Dim s As Double
s = 0
For z = 0 To aa_november
If Left(myArray_november(z, 1), how_digits) = Cells(k, nr_kolumny) Then
s = s + 1
End If
Next z
Erase myArray_november
Dim h As Double
Dim o As Double
o = 0
For h = 2 To k
If Cells(h, nr_kolumny) = Cells(k, nr_kolumny) Then
o = o + 1
End If
Next h
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = o - 1 'tutaj nr linii po filtrowaniu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
session.findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
session.findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarContextButton "&MB_FILTER"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").currentCellRow = 2
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").selectedRows = "2"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btnAPP_WL_SING").press
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btn600_BUTTON").press
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "Invoice"
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 7
session.findById("wnd[3]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").currentCellColumn = "BITM_DESCR"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
session.findById("wnd[2]/usr/ctxtDY_PATH").Text = path
If s = 0 Then
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & ".PDF"
Else
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & "-" & s + 1 & ".PDF"
End If
session.findById("wnd[2]/usr/ctxtDY_FILENAME").caretPosition = 5
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[12]").press
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Cells(k, ostatnia_kolumna) = "Checked"
Workbooks(name2).Save
End If
Next k
Workbooks("Saving_invoice").Activate
Cells(i, 3) = "Checked"
Workbooks("Saving_invoice.xlsm").Save
Workbooks(name2).Save
Workbooks(name2).Close
line999999999:
Next i
Workbooks("Saving_invoice.xlsm").Activate
If Cells(1, 11) = "action" Then
Columns("K:K").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
End If
Cells(1, 1).Activate
Workbooks("Saving_invoice.xlsm").Save
MsgBox ("Done")
End Sub
Well Application.Wait "The time at which you want the macro to resume, in Microsoft Excel date format." So it only pauses your VBA code but not "lets wait till some lines finishes work and we will continue" not sure how to write correctly :D bad in English. But hope you understood.
I suggest you to use Immediate window, and check everything is in place(values) with Debug.Print "My value: " & variable, also VBA is tricky and trying to make people less code while it automatically converts string, int and other stuff which is not declared or misspelled. So make on top "Option Explicit", then declare everything what is not declared.
And delete "On Error Resume Next", cause you cant see first error.

Alternative to Vlookup in VBA?

A strange question perhaps, but is there an alternative way of opening a workbook, searching for a particular reference in a column, and then pulling the data from a another column in that row using VBA, without using VLookup?
The table I am trying to get data from contains a mixture of numbers, text, dates, and the lookup value is often >13 digits long.
I sort of had something working with VLookup, but it was too inconsistent - every so often it would just break because the data type didn't match. An awful lot of 'type mismatch' or 'ByRef' errors - I'd get one right and then another breaks.
Unfortunately I don't know enough to know what to search to get me in the right direction.
If it helps explain what I'm trying to do, here's my code using VLookup that errors all the time:
Sub getData()
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
Dim wb As Workbook, src As Workbook
Dim srcRange As Range
Dim InputString
Dim strStatus
Dim strStatusNum
Dim strD1
Dim I As Integer
Set wb = ActiveWorkbook
I = 7
Set src = Workbooks.Open("D:\Files\test2.xlsx", True, True)
With src.Sheets(1)
Set srcRange = .Range(.Range("A1"), .Range("H1").End(xlDown))
End With
Do While wb.ActiveSheet.Cells(I, 1) <> ""
'Makes sure src.Close is called if errors
'On Error Resume Next
InputString = wb.Worksheets("Sheet 1").Cells(I, 1)
strStatus = Application.VLookup(InputString, srcRange, 3, False)
strD1 = Application.VLookup(InputString, srcRange, 4, False)
'Convert strStatus to actual number e.g. "03. no d1"
strStatusNum = Left(strStatus, 2)
wb.Worksheets("Sheet 1").Cells(I, 4) = strStatusNum
If (strStatusNum <> 3) Then
wb.Worksheets("Sheet 1").Cells(I, 2) = "Not at 03. No Work Order"
ElseIf (strStatusNum = 3) And (strD1 <> "") Then
wb.Worksheets("Sheet 1").Cells(I, 2) = "D1 Received"
wb.Worksheets("Sheet 1").Cells(I, 3) = strD1
Else
wb.Worksheets("Sheet 1").Cells(I, 2) = "No D1"
End If
I = I + 1
Loop
src.Close (False)
Application.EnableEvents = True
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.Calculation = xlAutomatic
End Sub
EDIT: Corrected some syntax.
You can use the Find method of the Range object, in your case of the column. The return value is the first cell (represented as another Range object) with a matching value, unless there is no match at all. Then Nothing is returned.
On the returned (single cell) range you can use the EntireRow method to get a Range that represents all the cells on the row of the found cell. On the returned (row) range you can use the Cells method to select the cell matching the column in the same row, that you want to return (again represented as another Range object).
By the way, a more flexible alternative to VLOOKUP in workbook functions is a combination of INDEX and MATCH.
Untested but compiled:
Sub getData()
Dim src As Workbook
Dim srcRange As Range
Dim strStatus, strStatusNum, strD1
Dim m, rw As Range
Set rw = ActiveSheet.Rows(7)
Set src = Workbooks.Open("D:\Files\test2.xlsx", True, True)
With src.Sheets(1)
Set srcRange = .Range(.Range("A1"), .Range("H1").End(xlDown))
End With
Do While rw.Cells(1).Value <> ""
m = Application.Match(rw.Cells(1), srcRange.Columns(1), 0)
If Not IsError(m) Then 'proceed only if got match
strStatus = srcRange.Cells(m, 3).Value
strD1 = srcRange.Cells(m, 4).Value
strStatusNum = Left(strStatus, 2)
rw.Cells(4).Value = strStatusNum
If strStatusNum <> 3 Then
rw.Cells(2) = "Not at 03. No Work Order"
ElseIf strStatusNum = 3 And strD1 <> "" Then
rw.Cells(2) = "D1 Received"
rw.Cells(3) = strD1
Else
rw.Cells(2) = "No D1"
End If
End If
Set rw = rw.Offset(1, 0)
Loop
src.Close False
End Sub
you may be after this refactoring of your code
Sub getData()
Dim wbRng As Range, cell As Range, f As Range
Dim strStatus, strStatusNum, strD1
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
With ActiveWorkbook.ActiveSheet
Set wbRng = .Range("A7:A" & WorksheetFunction.Max(7, .Cells(.Rows.count, 1).End(xlUp).Row)) '<--| set the range of values to be searched for
If WorksheetFunction.CountA(wbRng) = 0 Then Exit Sub '<--| exit if no values under row 7
Set wbRng = wbRng.SpecialCells(xlCellTypeConstants) '<--| narrow the range of values to be searched for down to not blank values only
End With
With Workbooks.Open("D:\Files\test2.xlsx", True, True).Sheets(1) '<--| open wanted workbook and reference its first sheet
With .Range("A1:A" & .Cells(.Rows.count, "H").End(xlUp).Row) '<--| reference its column A range from row 1 down to column H last not empty cell (this is your former "srcRange")
For Each cell In wbRng.SpecialCells(xlCellTypeConstants) '<--| loop through range of values to be searched for
Set f = .Find(what:=cell.Value, lookat:=xlWhole, LookIn:=xlValues) '<--| look referenced range for current value to be searched for
If Not f Is Nothing Then '<--| if found
strStatus = f.Offset(, 2).Value
strD1 = f.Offset(, 3).Value
'Convert strStatus to actual number e.g. "03. no d1"
strStatusNum = val(Left(strStatus, 2)) '<--| use 'Val()' function to convert string "03" to "3"
cell.Offset(, 3) = strStatusNum
Select Case True
Case strStatusNum <> 3
cell.Offset(, 1).Value = "Not at 03. No Work Order"
Case strStatusNum = 3 And (strD1 <> "")
cell.Offset(, 1).Resize(, 2).Value = Array("D1 Received", strD1)
Case Else
cell.Offset(, 1).Value = "No D1"
End Select
End If
Next
End With
.Parent.Close False
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.Calculation = xlAutomatic
End Sub

Memory Leak in vba code

I have created an automated macro which takes vehicle crash data from a csv file and automatically creates pivot table,charts and compares it to the previous year.
The code is approximately 1400 lines long and the data of the uploaded csv can be anywhere between 2 to 100 mb csv files with more than 100,000 rows and 36 columns.
The macro runs fine but it makes the machine very very slow and even causes it to crash most of the times. If I tab, to respond to an email, it has a high probability of crashing. Either the macro is continuing to try to do something after running successfully or it is keeping memory tied up after it has finished.
I need a way to optimize this. I have attached 3/4 of the entire macro.
Code:
Dim YEAR_COL, TYPE_COL As String
Dim CITY_COL, COUNTY_COL As String
Dim DOCNUM_COL, MONTH_COL As String
Dim COUNTY_CITY_COL, CRASH_DATE_COL As String
Dim INJ_TYPE_SERIOUS, INJ_TYPE_FATAL As Integer
Dim G_HEIGHT, G_WIDTH As Integer
Dim G_TOP, G_LEFT As Integer
Dim myColor1(12), myColor2(14) As Long
Dim CURR_YEAR As Integer, PREV_YEAR As Integer
Dim YEAR_NOT_FOUND_MSG As String
Dim INJ_TYPE_NOT_FOUND_MSG As String
Dim CATEGORY_TEXT As String
Dim UPLOADED_DATA_SHEET_NAME As String
Dim CURR_YEAR_SHEET_NAME As String
Dim PREV_YEAR_SHEET_NAME As String
Dim FILTERED_DATA_SHEET_NAME As String, DATA_SHEET_NAME As String
Dim SER_FAT_PLOT_SHEET As String
Dim SER_INJ_DATA_SHEET As String, FAT_INJ_DATA_SHEET As String
Dim SER_INJ_PIVOT_SHEET As String, FAT_INJ_PIVOT_SHEET As String
Dim CHART_SHEET As String
Dim CATEGORY_COL_NAME As String, CATEGORY_COL_NAME2 As String
Dim TOTAL_CATEGORIES As Integer, CATEGORY_TYPE As Integer
Dim SER_UNRESTRAINED_COL_NAME As String, FAT_UNRESTRAINED_COL_NAME As String
Dim ALCOHOL_COL_NAME As String, SPEED_COL_NAME As String
Dim TEEN_DRIVER_COL_NAME As String, OLD_DRIVER_COL_NAME As String
Dim DISTRACTION_COL_NAME As String, MOTORCYCLE_COL_NAME As String
Dim CMV_COL_NAME As String, BICYCLE_COL_NAME As String
Dim PEDESTRIAN_COL_NAME As String, LRG_TRUCK_COL_NAME As String
Dim CHART1_TITLE As String, CHART2_TITLE As String
Dim CHART3_TITLE As String, CHART4_TITLE As String
Dim INCREMENT_ROWS As Integer
Dim USE_EXISTING_DATA As Boolean
Private Sub InitializeVars()
TYPE_COL = "MinInjuryTypeID"
YEAR_COL = "Year"
CITY_COL = "City_Name"
COUNTY_COL = "County_Name"
COUNTY_CITY_COL = "County_City"
DOCNUM_COL = "DocumentNumber"
MONTH_COL = "MonthName"
CRASH_DATE_COL = "CrashDate"
INJ_TYPE_SERIOUS = 2
INJ_TYPE_FATAL = 1
CURR_YEAR = year(Now())
PREV_YEAR = CURR_YEAR - 1
TOTAL_YEARS = 5
CURR_YEAR_SHEET_NAME = "" & CURR_YEAR
PREV_YEAR_SHEET_NAME = "" & PREV_YEAR
INCREMENT_ROWS = 7500
' Speed, Alcohol, Unbelted, teen, old, texting, distraction
CATEGORY_TYPE = 0
CATEGORY_COL_NAME = ""
CATEGORY_COL_NAME2 = ""
FAT_UNRESTRAINED_COL_NAME = "unrestrainedFatals"
SER_UNRESTRAINED_COL_NAME = "UnrestrainedInjuries"
SPEED_COL_NAME = "Speed"
ALCOHOL_COL_NAME = "Alcohol"
CMV_COL_NAME = "CMV"
BICYCLE_COL_NAME = "Bicycle"
PEDESTRIAN_COL_NAME = "Pedestrian"
MOTORCYCLE_COL_NAME = "Motorcycle"
TEEN_DRIVER_COL_NAME = "TeenDriverInvolved"
OLD_DRIVER_COL_NAME = "OlderDriverInv"
LRG_TRUCK_COL_NAME = "LrgTruck"
DISTRACTION_COL_NAME = "DistractionInvolved"
YEAR_NOT_FOUND_MSG = "Please enter column name for filtering injury records by Year."
INJ_TYPE_NOT_FOUND_MSG = "Please enter column name for filtering by Injury Type."
G_TOP = 20
G_LEFT = 20
G_WIDTH = 2000
G_HEIGHT = 530
UPLOADED_DATA_SHEET_NAME = "Uploaded Data"
FILTERED_DATA_SHEET_NAME = "Filtered Data"
DATA_SHEET_NAME = "Data"
SER_INJ_DATA_SHEET = "Data(Ser_Injuries)"
FAT_INJ_DATA_SHEET = "Data(Fatalities)"
SER_INJ_PIVOT_SHEET = "Serious Injuries by County_City"
FAT_INJ_PIVOT_SHEET = "Fatalities by County_City"
SER_FAT_PLOT_SHEET = "Ser_Inj_Fatalities_Plot_Data"
CHART_SHEET = "Plots"
' color codes for difference chart
myColor1(1) = RGB(209, 190, 184)
myColor1(2) = RGB(196, 161, 149)
myColor1(3) = RGB(186, 133, 115)
myColor1(4) = RGB(191, 112, 86)
myColor1(5) = RGB(179, 85, 54)
myColor1(6) = RGB(163, 107, 88)
myColor1(7) = RGB(158, 93, 46)
myColor1(8) = RGB(191, 76, 38)
myColor1(9) = RGB(184, 56, 13)
myColor1(10) = RGB(145, 74, 23)
myColor1(11) = RGB(140, 42, 10)
myColor1(12) = RGB(115, 45, 22)
' color codes for total and difference chart
myColor2(1) = RGB(209, 190, 184)
myColor2(2) = RGB(196, 161, 149)
myColor2(3) = RGB(186, 133, 115)
myColor2(4) = RGB(191, 112, 86)
myColor2(5) = RGB(179, 85, 54)
myColor2(6) = RGB(163, 107, 88)
myColor2(7) = RGB(158, 93, 46)
myColor2(8) = RGB(191, 76, 38)
myColor2(9) = RGB(184, 56, 13)
myColor2(10) = RGB(145, 74, 23)
myColor2(11) = RGB(140, 42, 10)
myColor2(12) = RGB(115, 45, 22)
myColor2(13) = RGB(7, 162, 240)
myColor2(14) = RGB(255, 0, 0)
End Sub
Sub RunFullMacro()
Dim strFile As String
With Application
.Calculation = xlManual
.ScreenUpdating = False
.EnableEvents = False
End With
Call InitializeVars
'Call GetYearFromUser
strFile = GetYearForComparison()
Call GetFilterCategory
If USE_EXISTING_DATA = False Then
Call ImportCurrentYearCSV(strFile)
Call MoveDataToProperSheets(CURR_YEAR, CURR_YEAR_SHEET_NAME)
Call MoveDataToProperSheets(PREV_YEAR, PREV_YEAR_SHEET_NAME)
End If
CHART1_TITLE = "Difference in serious injuries" & CATEGORY_TEXT & " (" & PREV_YEAR & " - " & CURR_YEAR & ")"
CHART2_TITLE = "Difference in fatal injuries" & CATEGORY_TEXT & " (" & PREV_YEAR & " - " & CURR_YEAR & ")"
CHART3_TITLE = "Total number of crashes" & CATEGORY_TEXT & " with difference in number of serious injuries by month between " & _
PREV_YEAR & " and " & CURR_YEAR
CHART4_TITLE = "Total number of crashes" & CATEGORY_TEXT & " with difference in number of fatal injuries by month between " & _
PREV_YEAR & " and " & CURR_YEAR
Call CreateInitialDataSheets
Call ConcatenateColumns
Call CreateFilteredDataSheets
Call CreatePivotTables
Call CreatePlots
With Application
.Calculation = xlAutomatic
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Private Sub GetYearFromUser()
Dim userYear As String
Dim msg As String
msg = ""
EnterYear:
userYear = InputBox(Prompt:=msg & "Enter Year for comparing data:", title:="Year for comparing data")
' If no data entered, exit application
If userYear = "" Or userYear = vbNullString Then
MsgBox "Invalid Year." & vbNewLine & "Exiting."
End
ElseIf IsNumeric(userYear) = True Then
If CInt(userYear) > year(Now()) Then
msg = "Invalid Year. "
GoTo EnterYear
Else
CURR_YEAR = userYear
PREV_YEAR = CInt(userYear) - 1
End If
Else
msg = "Invalid Year. "
GoTo EnterYear
End If
' reinitialize variables
CURR_YEAR_SHEET_NAME = "" & CURR_YEAR
PREV_YEAR_SHEET_NAME = "" & PREV_YEAR
End Sub
Private Function GetYearForComparison()
Dim strFile As String
Dim answer As Integer
strFile = ""
If SheetExists(PREV_YEAR_SHEET_NAME) = False Or SheetExists(CURR_YEAR_SHEET_NAME) = False Then
USE_EXISTING_DATA = False
Else
USE_EXISTING_DATA = True
End If
If USE_EXISTING_DATA = True Then
answer = MsgBox("Do you want to use the existing data for comparison?", vbYesNo, "Use existing data")
If answer = vbYes Or answer = 6 Then
USE_EXISTING_DATA = True
Else
USE_EXISTING_DATA = False
End If
End If
' import sheet for current selected year
If USE_EXISTING_DATA = False Then
' strFile = "Macintosh HD:Users:sneha.banerjee:Sites:XLS:2016.csv"
' MsgBox "Uploading Data"
strFile = Application.GetOpenFilename("Csv Files (*.csv), *.csv", , "Please select a CSV file")
If strFile = "" Or strFile = vbNullString Then
'USE_EXISTING_DATA = True
MsgBox "Exiting..."
End
End If
End If
GetYearForComparison = strFile
End Function
Private Function SheetExists(ByVal name As String) As Boolean
On Error GoTo ReturnFalse
Sheets(name).Activate
' Sheet exists
SheetExists = True
Exit Function
ReturnFalse:
SheetExists = False
End Function
Private Sub ImportCurrentYearCSV(ByVal strFile As String)
Dim dataSheet As Worksheet
' assume previous years sheet already stored, store entered sheet as current year sheet
Call Get_Sheet(UPLOADED_DATA_SHEET_NAME, True)
Sheets(UPLOADED_DATA_SHEET_NAME).Activate
Set dataSheet = ActiveSheet
With dataSheet.QueryTables.Add(Connection:= _
"TEXT;" & strFile, Destination:=Range("A1"))
.name = "Uploaded Data"
.RefreshOnFileOpen = False
.BackgroundQuery = True
.SaveData = True
.AdjustColumnWidth = True
.TextFilePromptOnRefresh = False
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.Refresh BackgroundQuery:=False
End With
Application.CutCopyMode = False
'Move current year sheet after previous year
'currYearSheet.Move after:=Sheets(UPLOADED_DATA_SHEET_NAME)
'Move initial data sheet after current year
'Call Get_Sheet(DATA_SHEET_NAME, True)
'Sheets(DATA_SHEET_NAME).Move after:=Sheets(CURR_YEAR_SHEET_NAME)
End Sub
Private Sub MoveDataToProperSheets(ByVal CurrYear As Integer, ByVal sheetName As String)
Dim colNo As Integer
Dim rng1 As Range
Sheets(UPLOADED_DATA_SHEET_NAME).Activate
colNo = Search_ColumnWithTitle(YEAR_COL, "Please enter column name for Year")
With ActiveSheet
.AutoFilterMode = False
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter Field:=colNo, Criteria1:="" & CurrYear, Operator:=xlFilterValues
End With
Set rng1 = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible)
If rng1.Rows.count <= 1 Then
' Do nothing
Else
Call Get_Sheet(sheetName, True)
' Copy curr year's data to proper data sheet
Call CopyInPartsSpecial(UPLOADED_DATA_SHEET_NAME, rng1, sheetName)
End If
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
End Sub
Private Function Select_File_Mac() As String
Dim MyScript As String
Dim MyFile As String
'#If Mac Then
' strFile = Select_File_Mac()
'#Else
' strFile = Application.GetOpenFilename("Csv Files (*.csv), *.csv", , "Please select a CSV file")
'#End If¼
On Error Resume Next
' In the following statement, change true to false in the line "multiple
' selections allowed true" if you do not want to be able to select more
' than one file. Additionally, if you want to filter for multiple files, change
' {""com.microsoft.Excel.xls""} to
' {""com.microsoft.excel.xls"",""public.comma-separated-values-text""}
' if you want to filter on xls and csv files, for example.
MyScript = _
"set applescript's text item delimiters to "","" " & vbNewLine & _
"set the Files to (choose file of type " & _
" {""public.comma-separated-values-text""} " & _
"with prompt ""Please select a file"" default location alias """ & _
""" multiple selections allowed false) as string" & vbNewLine & _
"set applescript's text item delimiters to """" " & vbNewLine & _
"return the Files"
MyFile = MacScript(MyScript)
On Error GoTo 0
If MyFile <> "" Then
Select_File_Or_Files_Mac = MyFile
Else
Select_File_Or_Files_Mac = ""
End If
End Function
Private Sub CreateInitialDataSheets()
Dim ws As Worksheet
Dim rng As Range
Dim rng2 As Range, destCell As Range
' validate data for curr and prev years exist
If SheetExists(PREV_YEAR_SHEET_NAME) = False Then
MsgBox "Data for " & PREV_YEAR & " not found. Upload data and try again. " & vbNewLine & "Exiting."
End
ElseIf SheetExists(CURR_YEAR_SHEET_NAME) = False Then
MsgBox "Data for " & CURR_YEAR & " not found. Upload data and try again. " & vbNewLine & "Exiting."
End
End If
' Get latest date of current year data
Call Get_Sheet(DATA_SHEET_NAME, True)
Sheets(CURR_YEAR_SHEET_NAME).Activate
colNo = Search_ColumnWithTitle(CRASH_DATE_COL, "Please enter column name for Crash Date")
col2 = Search_ColumnWithTitle(TYPE_COL, "Please enter column name for Injury type")
lastRow = Get_LastRowNo(1)
lastCol = Get_LastColumnNo()
Set rng = ActiveSheet.Range(ActiveSheet.Cells(2, colNo), ActiveSheet.Cells(lastRow, colNo))
maxDate = Application.WorksheetFunction.Max(rng) - 365
' Get data less than equal to max date of previous year
Sheets(PREV_YEAR_SHEET_NAME).Activate
colNo = Search_ColumnWithTitle(CRASH_DATE_COL, "Please enter column name for Crash Date")
With ActiveSheet
.AutoFilterMode = False
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter Field:=colNo, Criteria1:="<=" & maxDate, Operator:=xlFilterValues
End With
' Copy previous year's data to data sheet
'ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheets(DATA_SHEET_NAME).Range("A1")
Call CopyInPartsSpecial(PREV_YEAR_SHEET_NAME, ActiveSheet.Cells.SpecialCells(xlCellTypeVisible), DATA_SHEET_NAME)
On Error GoTo Proceed
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
Proceed:
'Copy all current year to data sheet
Sheets(CURR_YEAR_SHEET_NAME).Activate
Set ws = ActiveSheet
Set rng2 = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol))
'Set destCell = Sheets(DATA_SHEET_NAME).Cells(Rows.Count, "A").End(xlUp).Offset(1)
'rng2.Copy Destination:=destCell
Call CopyInPartsSpecial(CURR_YEAR_SHEET_NAME, rng2, DATA_SHEET_NAME)
On Error GoTo Proceed1
Sheets(DATA_SHEET_NAME).Activate
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
Columns.AutoFit
Proceed1:
End Sub
Private Sub CreateFilteredDataSheets()
Dim colNo As Integer
If CATEGORY_TYPE = 0 Then
Application.DisplayAlerts = False
Call Get_Sheet(FILTERED_DATA_SHEET_NAME, True)
Sheets(FILTERED_DATA_SHEET_NAME).Delete
FILTERED_DATA_SHEET_NAME = DATA_SHEET_NAME
Application.DisplayAlerts = True
GoTo Exitsub
End If
' copy filtered data to new sheet
Call Get_Sheet(FILTERED_DATA_SHEET_NAME, True)
Sheets(DATA_SHEET_NAME).Activate
colNo = Search_ColumnWithTitle(CATEGORY_COL_NAME, "Please enter column name for Accident category")
If CATEGORY_TYPE = 3 Then
colNo = GetCategoryColumn()
With ActiveSheet
.AutoFilterMode = False
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter Field:=colNo, Criteria1:=">=1", Operator:=xlFilterValues
End With
Else
With ActiveSheet
.AutoFilterMode = False
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter Field:=colNo, Criteria1:=Array("Y", "YES"), Operator:=xlFilterValues
End With
End If
' Copy filtered data to new sheet
Call CopyInPartsSpecial(DATA_SHEET_NAME, ActiveSheet.Cells.SpecialCells(xlCellTypeVisible), FILTERED_DATA_SHEET_NAME)
On Error GoTo Proceed
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
Proceed:
' Delete temporary column
If CATEGORY_TYPE = 3 Then
Sheets(DATA_SHEET_NAME).Columns(colNo).ClearContents
End If
Exitsub:
Sheets(FILTERED_DATA_SHEET_NAME).Activate
Columns.AutoFit
End Sub
Private Sub ConcatenateColumns()
Dim col1 As Integer, col2 As Integer
Dim rowCount As Long, resultCol As Integer
Sheets(DATA_SHEET_NAME).Activate
col1 = Search_ColumnWithTitle(COUNTY_COL, "Please enter column name for County")
col2 = Search_ColumnWithTitle(CITY_COL, "Please enter column name for City")
rowCount = Get_LastRowNo(1)
' Find first available column for results
If IsError(Application.Match(COUNTY_CITY_COL, Range(Cells(1, 1), Cells(1, Columns.count)), 0)) Then
' column not present, find first empty column
resultCol = Get_LastColumnNo() + 1
Else
' column already present, clear it
resultCol = Application.Match(COUNTY_CITY_COL, Range(Cells(1, 1), Cells(1, Columns.count)), 0)
Columns(resultCol).ClearContents
End If
' Populate Final results
Cells(1, resultCol).value = COUNTY_CITY_COL
For rowNo = 2 To rowCount
Cells(rowNo, resultCol).value = Trim(Cells(rowNo, col1).value & Cells(rowNo, col2).value)
Next
Columns(resultCol).Select
Selection.EntireColumn.AutoFit
Application.CutCopyMode = False
End Sub
Private Function GetCategoryColumn()
Dim col1 As Integer, col2 As Integer
Dim rowCount As Long, resultCol As Integer
Sheets(DATA_SHEET_NAME).Activate
col1 = Search_ColumnWithTitle(CATEGORY_COL_NAME, "Please enter column name for Unbelted Fatalities")
col2 = Search_ColumnWithTitle(CATEGORY_COL_NAME2, "Please enter column name for Unbelted Serious Injuries")
rowCount = Get_LastRowNo(1)
resultCol = Get_LastColumnNo() + 1
' Populate Final values
Cells(1, resultCol).value = "TEMP_COL"
For rowNo = 2 To rowCount
If IsTrue(Cells(rowNo, col1).value) Or IsTrue(Cells(rowNo, col2).value) Then
Cells(rowNo, resultCol).value = 1
Else
Cells(rowNo, resultCol).value = 0
End If
Next
Columns(resultCol).Select
Selection.EntireColumn.AutoFit
Application.CutCopyMode = False
GetCategoryColumn = resultCol
End Function
Private Function IsTrue(ByVal value As String) As Boolean
Dim returnValue As Integer
If IsNumeric(value) Then
If CInt(value) > 0 Then
returnValue = 1
Else
returnValue = 0
End If
ElseIf value = "YES" Or value = "Y" Then
returnValue = 1
Else
returnValue = 0
End If
IsTrue = returnValue
End Function
Private Sub CreatePivotTables()
Dim colNo As Integer
Sheets(FILTERED_DATA_SHEET_NAME).Activate
colNo = Search_ColumnWithTitle(TYPE_COL, INJ_TYPE_NOT_FOUND_MSG)
Call CreateDataSheet(INJ_TYPE_SERIOUS, colNo, SER_INJ_DATA_SHEET)
Call CreateDataSheet(INJ_TYPE_FATAL, colNo, FAT_INJ_DATA_SHEET)
On Error GoTo Proceed
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
Proceed:
Sheets(SER_INJ_DATA_SHEET).Activate
Call CreatePivotTable(SER_INJ_PIVOT_SHEET)
Sheets(FAT_INJ_DATA_SHEET).Activate
Call CreatePivotTable(FAT_INJ_PIVOT_SHEET)
End Sub
Private Sub CreateDataSheet(ByVal val As Integer, ByVal colNo As Integer, ByVal sheetName As String)
With ActiveSheet
.AutoFilterMode = False
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter
.Range(Cells(1, 1), Cells(1, Columns.count)).AutoFilter Field:=colNo, Criteria1:=val
End With
' verify sheet is present and clear it, else create new
Call Get_Sheet(sheetName, True)
' copy data sheet to new sheet
Sheets(FILTERED_DATA_SHEET_NAME).Activate
'ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheets(sheetName).Range("A1")
Call CopyInPartsSpecial(FILTERED_DATA_SHEET_NAME, ActiveSheet.Cells.SpecialCells(xlCellTypeVisible), sheetName)
On Error GoTo Proceed
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
ActiveSheet.AutoFilterMode = False
End If
Proceed:
Sheets(sheetName).Activate
Columns.AutoFit
Sheets(FILTERED_DATA_SHEET_NAME).Activate
End Sub
Private Sub CreatePivotTable(ByVal pvtShtName As String)
Dim pivotSheet As Worksheet
Dim dataSheet As String
dataSheet = ActiveSheet.name
' Create Pivot Sheet
Call Get_Sheet(pvtShtName, True)
Set pivotSheet = Sheets(pvtShtName)
' select data source for pivot table
Sheets(dataSheet).Activate
resultCol = Application.Match(COUNTY_CITY_COL, Range(Cells(1, 1), Cells(1, Columns.count)), 0)
rowCount = Get_LastRowNo(1)
srcData = ActiveSheet.name & "!" & Range(Cells(1, 1), Cells(rowCount, resultCol)).Address(ReferenceStyle:=xlR1C1)
' Create Pivot Cache from Source Data
Set pvtCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=srcData)
pivotSheet.Activate
Set pvt = pvtCache.CreatePivotTable(TableDestination:=Range("A1"), TableName:="PT_" & pvtShtName)
' Specify row and column fields
With pvt.PivotFields(YEAR_COL)
.Orientation = xlColumnField
.PivotFilters.Add Type:=xlCaptionIsGreaterThanOrEqualTo, Value1:=PREV_YEAR
End With
pvt.PivotFields(MONTH_COL).Orientation = xlColumnField
With pvt.PivotFields(COUNTY_CITY_COL)
.Orientation = xlRowField
.AutoSort xlAscending, COUNTY_CITY_COL
End With
With pvt.PivotFields(DOCNUM_COL)
.Orientation = xlDataField
.Function = xlCount
End With
Application.CutCopyMode = False
End Sub
Private Function Get_LastRowNo(ByVal colNo As Integer) As Long
Get_LastRowNo = Cells(Rows.count, colNo).End(xlUp).Row
End Function
Private Function Get_LastColumnNo() As Integer
Get_LastColumnNo = Cells(1, Columns.count).End(xlToLeft).Column
End Function
Private Function Get_Sheet(ByVal sheetName As String, ByVal clearSheet As Boolean) As Boolean
Dim ws As Worksheet
Dim dataSheet As String
Dim chtObj As ChartObject
' Check if sheet present, if not create new
dataSheet = ActiveSheet.name
On Error GoTo CreateSheet
Set ws = Sheets(sheetName)
If clearSheet = True Then
ws.Cells.Clear
End If
' Delete all existing charts
For Each chtObj In ws.ChartObjects
chtObj.Delete
Next
Sheets(dataSheet).Activate
Get_Sheet = False
Exit Function
CreateSheet:
' If current sheet empty, rename it and use it
If ActiveSheet.UsedRange.Rows.count = 1 _
And ActiveSheet.UsedRange.Columns.count = 1 And Cells(1, 1).value = "" Then
ActiveSheet.name = sheetName
Else
Sheets.Add(, ActiveSheet).name = sheetName
Sheets(dataSheet).Activate
End If
Get_Sheet = True
End Function
' Assuming ActiveSheet and title on Row 1
Private Function Search_ColumnWithTitle(ByVal title As String, ByVal msg As String) As Integer
CheckColumn:
If IsError(Application.Match(title, Range(Cells(1, 1), Cells(1, Columns.count)), 0)) Then
title = InputBox(Prompt:="Column '" & title & "' not found. " & msg, _
title:="Enter " & title & " column name")
If title = "" Or title = vbNullString Then
MsgBox "No column name entered. Exiting..."
End
Else
GoTo CheckColumn
End If
End If
Search_ColumnWithTitle = Application.Match(title, Range(Cells(1, 1), Cells(1, Columns.count)), 0)
End Function
Private Sub GetFilterCategory()
Dim categoryNum As String
Dim text As String
TOTAL_CATEGORIES = 11
text = "0. All categories" & vbNewLine & _
"1. Alcohol" & vbNewLine & _
"2. Speed" & vbNewLine & _
"3. Unrestrained" & vbNewLine & _
"4. CMV" & vbNewLine & _
"5. Bicylce" & vbNewLine & _
"6. Pedestrian" & vbNewLine & _
"7. Motorcycle" & vbNewLine & _
"8. Teen driver involved" & vbNewLine & _
"9. Older driver involved" & vbNewLine & _
"10. Large Truck" & vbNewLine & _
"11. Distraction involved" & vbNewLine & _
"Enter the category number to be filtered"
categoryNum = InputBox(Prompt:=text, title:="Filter accidents by category")
If IsNumeric(categoryNum) Then
If CInt(categoryNum) >= 0 And CInt(categoryNum) <= TOTAL_CATEGORIES Then
CATEGORY_TYPE = CInt(categoryNum)
Else
CATEGORY_TYPE = 0
End If
Else
MsgBox "Invalid Entry. Exiting..."
End
End If
Select Case CATEGORY_TYPE
Case 1
CATEGORY_COL_NAME = ALCOHOL_COL_NAME
CATEGORY_TEXT = " - Alcohol -"
Case 2
CATEGORY_COL_NAME = SPEED_COL_NAME
CATEGORY_TEXT = " - Speeding -"
Case 3
CATEGORY_COL_NAME = FAT_UNRESTRAINED_COL_NAME
CATEGORY_COL_NAME2 = SER_UNRESTRAINED_COL_NAME
CATEGORY_TEXT = " - Unrestrained -"
Case 4
CATEGORY_COL_NAME = CMV_COL_NAME
CATEGORY_TEXT = " - CMV -"
Case 5
CATEGORY_COL_NAME = BICYCLE_COL_NAME
CATEGORY_TEXT = " - Bicycle -"
Case 6
CATEGORY_COL_NAME = PEDESTRIAN_COL_NAME
CATEGORY_TEXT = " - Pedestrian -"
Case 7
CATEGORY_COL_NAME = MOTORCYCLE_COL_NAME
CATEGORY_TEXT = " - Motorcycle -"
Case 8
CATEGORY_COL_NAME = TEEN_DRIVER_COL_NAME
CATEGORY_TEXT = " - Teen driver -"
Case 9
CATEGORY_COL_NAME = OLD_DRIVER_COL_NAME
CATEGORY_TEXT = " - Older driver -"
Case 10
CATEGORY_COL_NAME = LRG_TRUCK_COL_NAME
CATEGORY_TEXT = " - Large truck -"
Case 11
CATEGORY_COL_NAME = DISTRACTION_COL_NAME
CATEGORY_TEXT = " - Distraction -"
Case Else
CATEGORY_COL_NAME = ""
CATEGORY_TEXT = ""
End Select
End Sub
Private Function ExitIfColumnNotFound(ByVal colName As String)
If IsError(Application.Match(colName, Range(Cells(1, 1), Cells(1, Columns.count)), 0)) Then
MsgBox "Column '" & colName & "' not found. Exiting..."
End
End If
End Function

Show columns placed in multiple ranges

I have multiple Excel files with the following structure:
Each file has the exact same columns (Apples, Oranges, Bananas, etc.) but placed under different letters throughout the sheets. For example, column "Apples" is under letter A in the first 5 sheets, but it's under letter C in the rest of the sheets. This order is not consistent and varies in each file.
I would like a macro capable of:
Unwrap all the cells in all sheets.
Hide columns from A to Z in all sheets.
Unhide only three columns featuring the words "apples/apple", "oranges/orange" and "bananas/bananas" in row 1.
Shrink to fit the text in the "apples/apple" column and set the width to 120.
Wrap to fit the text on the "oranges/orange" and "bananas/bananas" columns and set the width to 350.
Zoom all sheets to 100%.
I have this macro that works like a charm, as it allows me to choose which three columns I want to keep. However, it works exclusively if they are placed in the exact same order in all sheets:
Sub AdjustTF()
ColumnWidth = 10
ActiveWindow.Zoom = 100
Dim wsh As Worksheet
Dim rng As Range
Dim i As Long
Dim f As Boolean
Dim c As Long
On Error GoTo ErrHandler
' The following two lines are optional
Worksheets(1).Select
Range("A1").Select
For Each wsh In Worksheets
wsh.Cells.WrapText = False
wsh.Cells.VerticalAlignment = xlBottom
wsh.Cells.HorizontalAlignment = xlLeft
wsh.Cells.EntireColumn.Hidden = False
If f = False Then
Set rng = Application.InputBox( _
Prompt:="Select the columns to keep.", _
Type:=8).EntireColumn
f = True
End If
Set rng = wsh.Range(rng.Address).EntireColumn
c = wsh.Cells.Find(What:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
wsh.Range(wsh.Cells(1, 1), wsh.Cells(1, c)).EntireColumn.Hidden = True
With rng
.Hidden = False
With .Areas(1)
.ColumnWidth = 3
For i = 1 To 3
.ColumnWidth = 120 / .Width * .ColumnWidth
Next i
.ShrinkToFit = True
End With
With .Areas(2)
.ColumnWidth = 8
For i = 1 To 3
.ColumnWidth = 350 / .Width * .ColumnWidth
Next i
.WrapText = True
End With
With .Areas(3)
.ColumnWidth = 8
For i = 1 To 3
.ColumnWidth = 350 / .Width * .ColumnWidth
Next i
.WrapText = True
End With
End With
wsh.Cells.EntireRow.AutoFit
NextSheet:
Next wsh
Application.Goto Worksheets(1).Range("A1"), True
Exit Sub
ErrHandler:
Select Case Err
Case 424 ' Object required
Resume NextSheet
Case Else
MsgBox Err.Description, vbExclamation
End Select
End Sub
EDIT: I've also this code, which is significantly lighter (even though doesn't quite perform all tasks I wanted) but for some reasons works only with a single file and not when assigned to my Personal.xls sheet.
Sub AdjustTFAlternate()
Dim R As Range
Dim Ws As Worksheet
Dim Item
'In each worksheet
For Each Ws In ActiveWorkbook.Worksheets
'Hide all columns
Ws.UsedRange.EntireColumn.Hidden = True
'Search for this words
For Each Item In Array("apple*", "orange*", "banana*")
'Search for a keyword in the 1st row
Set R = Ws.Rows(1).Find(Item, LookIn:=xlFormulas, LookAt:=xlWhole)
If R Is Nothing Then
'Not found
Exit For
End If
'Unhide this column
R.EntireColumn.Hidden = False
Next
Next
End Sub
If you simply want a popup box for the user to select the 3 columns on each sheet, remove the line that reads
f = True
that is inside the If f = False Then statement.
If you want the macro to "remember" the column headers for each column chosen on the first page, then you'll need to modify the code slightly (and make some assumptions):
Assumptions
The column headers are in the first row
The column headers are unique (i.e., you don't have the same column title multiple times in the same sheet).
EDIT:
Code will now store all selected columns in an array that will search on each worksheet. For example, if on worksheet 1 you have apple, banana, and coconut, you will get an initial InputBox. If on worksheet 3, you now have apples, bananas, and coconuts, then you will get a second InputBox asking for these values. Now, on worksheets 4-n, the code will search for either apple or apples.
Code
Sub AdjustTF()
ColumnWidth = 10
Dim wsh As Worksheet
Dim rng As Range
Dim i As Long
Dim f As Boolean
Dim c As Long
'Dim aCol(1 To 1, 1 To 3) As String
Dim aCol() As String
ReDim aCol(1 To 3, 1 To 1)
Dim iCol(1 To 3) As Integer
Dim iTemp As Integer
Dim uStr As String
On Error GoTo ErrHandler
' The following two lines are optional
Worksheets(1).Select
Range("A1").Select
For Each wsh In Worksheets
d = 1
wsh.Cells.WrapText = False
wsh.Cells.VerticalAlignment = xlBottom
wsh.Cells.HorizontalAlignment = xlLeft
wsh.Cells.EntireColumn.Hidden = False
If f = False Then
On Error Resume Next
Err.Number = 0
Set rng = Application.InputBox( _
Prompt:="Select the columns to keep.", _
Type:=8).EntireColumn
If Err.Number > 0 Then
Exit Sub
End If
On Error GoTo ErrHandler
f = True
aCol(1, 1) = wsh.Cells(1, rng.Areas(1).Column).Value
aCol(2, 1) = wsh.Cells(1, rng.Areas(2).Column).Value
aCol(3, 1) = wsh.Cells(1, rng.Areas(3).Column).Value
Else
On Error Resume Next
For a = 1 To 3
iCol(a) = 0
Next
For a = 1 To UBound(aCol, 2)
Err.Number = 0
iTemp = wsh.Cells.Find(what:=aCol(1, a), lookat:=xlWhole).Column
If Err.Number = 0 And iCol(1) = 0 Then iCol(1) = iTemp
Err.Number = 0
iTemp = wsh.Cells.Find(what:=aCol(2, a), lookat:=xlWhole).Column
If Err.Number = 0 And iCol(2) = 0 Then iCol(2) = iTemp
Err.Number = 0
iTemp = wsh.Cells.Find(what:=aCol(3, a), lookat:=xlWhole).Column
If Err.Number = 0 And iCol(3) = 0 Then iCol(3) = iTemp
If iCol(1) > 0 And iCol(2) > 0 And iCol(3) > 0 Then Exit For
Next
If iCol(1) = 0 Or iCol(2) = 0 Or iCol(3) = 0 Then
wsh.Activate
Err.Number = 0
Set rng = Application.InputBox( _
Prompt:="Select the columns to keep.", _
Type:=8).EntireColumn
If Err.Number > 0 Then
Exit Sub
End If
a = UBound(aCol, 2) + 1
ReDim Preserve aCol(1 To 3, 1 To a)
aCol(1, a) = wsh.Cells(1, rng.Areas(1).Column).Value
aCol(2, a) = wsh.Cells(1, rng.Areas(2).Column).Value
aCol(3, a) = wsh.Cells(1, rng.Areas(3).Column).Value
Else
uStr = Range(wsh.Cells(1, iCol(1)), wsh.Cells(1, iCol(1))).Address & "," & _
Range(wsh.Cells(1, iCol(2)), wsh.Cells(1, iCol(2))).Address & "," & _
Range(wsh.Cells(1, iCol(3)), wsh.Cells(1, iCol(3))).Address
Set rng = Range(uStr)
End If
On Error GoTo ErrHandler
End If
Set rng = wsh.Range(rng.Address).EntireColumn
c = wsh.Cells.Find(what:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
wsh.Range(wsh.Cells(1, 1), wsh.Cells(1, c)).EntireColumn.Hidden = True
With rng
.Hidden = False
With .Areas(1)
.ColumnWidth = 3
For i = 1 To 3
.ColumnWidth = 120 / .Width * .ColumnWidth
Next i
.ShrinkToFit = True
End With
With .Areas(2)
.ColumnWidth = 8
For i = 1 To 3
.ColumnWidth = 350 / .Width * .ColumnWidth
Next i
.WrapText = True
End With
With .Areas(3)
.ColumnWidth = 8
For i = 1 To 3
.ColumnWidth = 350 / .Width * .ColumnWidth
Next i
.WrapText = True
End With
End With
wsh.Cells.EntireRow.AutoFit
wsh.Activate
ActiveWindow.Zoom = 100
wsh.Cells(1, 1).Select
NextSheet:
Next wsh
Application.Goto Worksheets(1).Range("A1"), True
Exit Sub
ErrHandler:
Select Case Err
Case 424 ' Object required
Resume NextSheet
Case Else
MsgBox Err.Description, vbExclamation
End Select
End Sub

Find if a given value is in a cell, if so then try next value until unique

I have the below sub that checks on a separate worksheet if the created number in textbox8 already exists, at the moment there is a message box that alerts the user that the part number already exists, they have to click OK, then the number is incremented by 1, the process is repeated until a unique number is found. This is the written to the worksheet along with some other data.
What I need to do is remove the message box so it will automatically search and find the next available number.
I added the following code to the sub, but this has no effect:
Application.DisplayAlerts = False
MsgBox "This already exists"
SendKeys "{ENTER}"
Application.DisplayAlerts = True
code
'Create part number and check
Private Sub CommandButton2_Click()
With TextBox26
If myreset = True Then
.Tag = 0
myreset = False
End If
.Tag = Val(.Tag) + 1
.Text = "-" & VBA.Format(Val(.Tag), "0000")
End With
Dim iNum(1 To 8) As String
iNum(1) = TextBox24.Value
iNum(2) = TextBox25.Value
iNum(3) = TextBox26.Value
TextBox8.Value = iNum(1) + iNum(2) + iNum(3)
'check article exists
Dim emptyRow As Long
Dim rcnt As Long
Dim i As Long
ActiveWorkbook.Sheets("existing").Activate
rcnt = Sheets("existing").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To rcnt
If TextBox8.Text = Sheets("existing").Range("A" & i).Value Then
Application.DisplayAlerts = False
MsgBox "This already exists"
SendKeys "{ENTER}"
Application.DisplayAlerts = True
Exit Sub
End If
Next
Range("A1").Select
Do
If IsEmpty(ActiveCell) = False Then
ActiveCell.Offset(1, 0).Select
End If
Loop Until IsEmpty(ActiveCell) = True
ActiveCell.Value = TextBox8.Text
To remove the message Box all you need to do is delete the following lines in your code
Application.DisplayAlerts = False
MsgBox "This already exists"
SendKeys "{ENTER}"
Application.DisplayAlerts = True
I am not sure what the first part of the code is doing. if you could provide some example I can help with that. But I have rationalized the second part and this will now achieve what the original code was attempting to achieve with lesser lines.
'check article exists
Dim emptyRow As Long
Dim rcnt As Long
Dim i As Long
Dim varProdCode As Long
ActiveWorkbook.Sheets("existing").Activate
varProdCode = TextBox8.Text
rcnt = Sheets("existing").Range("A" & Rows.Count).End(xlUp).Row
Do Until varProdCode = 0
For i = 2 To rcnt
If varProdCode = Sheets("existing").Range("A" & i).Value Then
varProdCode = varProdCode + 1
Exit For
Else
Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = varProdCode
varProdCode = 0
Exit Sub
End If
Next
Loop
This is the code that works
Private Sub CommandButton2_Click()
With TextBox26
If myreset = True Then
.Tag = 0
myreset = False
End If
.Tag = Val(.Tag) + 1
.Value = VBA.Format(Val(.Tag), "0000")
End With
Dim emptyRow As Long
Dim rcnt As Long
Dim c As Long
rcnt = Sheets("existing").Range("A" & Rows.Count).End(xlUp).Row
For c = 2 To rcnt
Dim iNum(1 To 8) As String
iNum(1) = TextBox24.Value
iNum(2) = TextBox25.Value
iNum(3) = TextBox26.Value
'check if article exists
ActiveWorkbook.Sheets("existing").Activate
If Sheets("existing").Range("A" & c).Value = iNum(1) & iNum(2) & "-" & iNum(3) Then
TextBox26.Value = TextBox26.Value + 1
iNum(3) = TextBox26.Value
End If
Next c
'create article number
TextBox8.Value = iNum(1) + iNum(2) + "-" + iNum(3)
'select first column
Range("A1").Select