Related
Here is my code below that opens up yesterdays file Tuesday-Friday and the last 3 days on a Monday.
There is now a need to make a weekly version of this and i feel the code may get too long.
Is there a better way to do this then recreating the loop 7 times?
I am thinking i could do another loop that says that while column G (which only has information if updated in ) is empty then take the date in the respective cell in column A and keep opening files from the date in column A to yesterdays date? (pic for reference on what i mean) so it would fill every day from 13/09/2021 to 19/09/2021.
Also it would be nice if anyone had any pointers about making this code more robust and/or efficient as I am quite new to VBA.
Sub OpenManagersFileAndSelectColumns()
Dim directory As String, fileName As String, sheet As Worksheet, total As Integer, directory3day As String, fileName3day As String, directory2day As String, fileName2day As String, DateStringFS As String, AlteryxFP As String
' Turn off screen updating and displaying alerts.
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' Creating Dynamic Elements for directories and file names.
' Create the year, day amd month year
'For - 1 Days (used in two places)
YearString = Format((Date - 1), "yyyy")
MonthYearString = Format((Date - 1), "mmm yyyy")
DateString = Format((Date - 1), "dd-mm-yyyy")
'For - 2 Days
YearString2day = Format((Date - 2), "yyyy")
MonthYearString2day = Format((Date - 2), "mmm yyyy")
DateString2day = Format((Date - 2), "dd-mm-yyyy")
'For - 3 Days
YearString3day = Format((Date - 3), "yyyy")
MonthYearString3day = Format((Date - 3), "mmm yyyy")
Dim DateString3day As String
'Date for File Name
DateStringFS = Format((Date), "dd.mm.yy")
'Gets username of the device for comp and whether or not
comp = Environ("username")
'Gets Alteryx Output
If Environ("username") = "SP" Then
AlteryxFP = "Alteryx Output\"
Else
AlteryxFP = ""
End If
' Initialize the variable directory. We use the Dir function to find the first *.csv ?? file stored in this directory. ( this can be changed to xls if necessary
'For Today - 1 day (used in two places)
directory = "C:\Users\" & comp & "\Dropbox (SHG)\" & AlteryxFP & "\Daily Finance & Revenue Data\1. Daily Occupancy Output\Site 5\" & YearString & "\" & MonthYearString & "\" & DateString & "\"
'For Today - 2 Days
directory2day = "C:\Users\" & comp & "\Dropbox (SHG)\" & AlteryxFP & "\Daily Finance & Revenue Data\1. Daily Occupancy Output\Site 5\" & YearString2day & "\" & MonthYearString2day & "\" & DateString2day & "\"
'For Today - 3 Days
directory3day = "C:\Users\" & comp & "\Dropbox (SHG)\" & AlteryxFP & "\Daily Finance & Revenue Data\1. Daily Occupancy Output\Site 5\" & MonthYearString3day & "\" & DateString3day & "\"
'Ensures the current file is activated and clears previous content.
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Rows("4:7").Select
Selection.ClearContents
'If its a monday then it will open the last 3 days, it is the rest of the week it will open the previous day.
If Format(Date, "w") = 2 Then
' Today - 1 days
fileName = Dir(directory & "*manager*.csv")
' The variable fileName now holds the name of the first Excel file found in the directory. Add a Do While Loop.
Do While fileName <> ""
' There is no simple way to copy worksheets from closed Excel files. Therefore we open the Excel file.
Workbooks.Open (directory & fileName), local:=True
' Import the sheets from the Excel file into import-sheet.xls.
For Each sheet In Workbooks(fileName).Worksheets
total = Workbooks("YORYK Daily Report " & DateStringFS & "$.xlsb").Worksheets.Count
Windows(fileName).Activate
' If the date in the file is TODAY -1 then accept, otherwise error message.
If Range("AG2") = (Date - 1) Then
Rows("2:2").Select
Selection.Copy
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Rows("7:7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("A4:AG5").Select
Application.CutCopyMode = False
Else
MsgBox "Date in file does not match " & DateString
' End If for checking the date for day - 1
End If
Next sheet
'Close the Excel file.
Workbooks(fileName).Close
'The Dir function is a special function. To get the other Excel files, you can use the Dir function again with no arguments.
fileName = Dir()
'Note: When no more file names match, the Dir function returns a zero-length string ("").
'As a result, Excel VBA will leave the Do While loop.
'End of loop for day - 1 file open and paste.
Loop
' Today - 2 days.
fileName2day = Dir(directory2day & "*manager*.csv")
' The variable fileName now holds the name of the first Excel file found in the directory. Add a Do While Loop.
Do While fileName2day <> ""
' There is no simple way to copy worksheets from closed Excel files. Therefore we open the Excel file.
Workbooks.Open (directory2day & fileName2day), local:=True
' Import the sheets from the Excel file into this sheet.
For Each sheet In Workbooks(fileName2day).Worksheets
total = Workbooks("YORYK Daily Report " & DateStringFS & "$.xlsb").Worksheets.Count
Windows(fileName2day).Activate
If Range("AG2") = Date - 2 Then
Rows("2:2").Select
Selection.Copy
Sheets("Actual data").Activate
Rows("6:6").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Else
MsgBox "Date in file does not match " & DateString2day
End If
Next sheet
'Close the Excel file.
Workbooks(fileName2day).Close
'The Dir function is a special function. To get the other Excel files, you can use the Dir function again with no arguments.
fileName2day = Dir()
'Note: When no more file names match, the Dir function returns a zero-length string ("").
'As a result, Excel VBA will leave the Do While loop.
Loop
' Today - 3 days
fileName3day = Dir(directory3day & "*manager*.csv")
' The variable fileName now holds the name of the first Excel file found in the directory. Add a Do While Loop.
Do While fileName3day <> ""
' There is no simple way to copy worksheets from closed Excel files. Therefore we open the Excel file.
Workbooks.Open (directory3day & fileName3day), local:=True
' Import the sheets from the Excel file into import-sheet.xls.
For Each sheet In Workbooks(fileName3day).Worksheets
total = Workbooks("YORYK Daily Report " & DateStringFS & "$.xlsb").Worksheets.Count
Windows(fileName3day).Activate
'If Date in file is TODAY - 3 then accept and paste info otherwise error message.
If Range("AG2") = Date - 3 Then
Rows("1:2").Select
Selection.Copy
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Rows("4:5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Else
MsgBox "Date in file does not match " & DateString3day
' End If for day - 3
End If
Next sheet
'Close the Excel file.
Workbooks(fileName3day).Close
'The Dir function is a special function. To get the other Excel files, you can use the Dir function again with no arguments.
fileName3day = Dir()
'Note: When no more file names match, the Dir function returns a zero-length string ("").
'As a result, Excel VBA will leave the Do While loop.
'End Loop for Today - 3
Loop
' End of loop, now cleaning data, for 3 days section
' Next step is to select the right columns of data and run calculations to get TR, RR, OCC, OOO, ADR for the 3 day period.
Range("A4:AF7").Select
Selection.delete Shift:=xlToLeft
Range("K4:AD7").Select
Selection.delete Shift:=xlToLeft
Range("AE4:DO7").Select
Selection.delete Shift:=xlToLeft
Range("AF4:AT7").Select
Selection.delete Shift:=xlToLeft
Range("AH4:CE7").Select
Selection.delete Shift:=xlToLeft
Columns("AE:AG").Select
Selection.Cut
Columns("C:C").Select
Selection.INSERT Shift:=xlToRight
Columns("F:M").Select
Selection.INSERT Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Columns("A:A").Select
Selection.NumberFormat = "m/d/yyyy"
Range("G4").Select
ActiveCell.FormulaR1C1 = "Rms"
Range("H4").Select
ActiveCell.FormulaR1C1 = "G Rms"
Range("I4").Select
ActiveCell.FormulaR1C1 = "Rm Rev"
Range("J4").Select
ActiveCell.FormulaR1C1 = "ADR"
Range("K4").Select
ActiveCell.FormulaR1C1 = "OOO Rms"
Range("L4").Select
ActiveCell.FormulaR1C1 = "Total Rev"
Range("G5").Select
ActiveCell.FormulaR1C1 = "=RC[-4]+RC[-3]"
Range("I5").Select
ActiveCell.FormulaR1C1 = "=RC[-7]-RC[13]"
Range("J5").Select
ActiveCell.FormulaR1C1 = "=RC[-1]/RC[-3]"
Range("K5").Select
ActiveCell.FormulaR1C1 = "=RC[-6]"
Range("L5").Select
ActiveCell.FormulaR1C1 = "=SUM(RC[-10],RC[2]:RC[9])-SUM(RC[10]:RC[29])"
Range("G5:L5").Select
Selection.AutoFill Destination:=Range("G5:L7"), Type:=xlFillDefault
Range("G5:L7").Select
Range("G4").Select
' Colouring the titles to get notify it is done.
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Rms"
Range("H4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "G Rms"
Range("I4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Rm Rev"
Range("J4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "ADR"
Range("K4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "OOO Rms"
Range("L4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Total Rev"
Range("G4:L4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0
.PatternTintAndShade = 0
End With
' This else is for days where day does not = monday, so any other day of the week.
Else
fileName = Dir(directory & "*manager*.csv")
' The variable fileName now holds the name of the first Excel file found in the directory. Add a Do While Loop.
Do While fileName <> ""
' There is no simple way to copy worksheets from closed Excel files. Therefore we open the Excel file.
Workbooks.Open (directory & fileName), local:=True
' Import the sheets from the forecast file into this sheet
For Each sheet In Workbooks(fileName).Worksheets
total = Workbooks("YORYK Daily Report " & DateStringFS & "$.xlsb").Worksheets.Count
Windows(fileName).Activate
If Range("AG2") = Date - 1 Then
Rows("1:2").Select
Selection.Copy
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Rows("4:5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Else
MsgBox "Date in file does not match " & DateString
End If
Next sheet
'Close the Excel file.
Workbooks(fileName).Close
'The Dir function is a special function. To get the other Excel files, you can use the Dir function again with no arguments.
fileName = Dir()
'Note: When no more file names match, the Dir function returns a zero-length string ("").
'As a result, Excel VBA will leave the Do While loop.
Loop
' End of loop, for 1 day set up, now cleaning data
' Next step is to select the right columns of data and run calculations to get TR, RR, OCC, OOO, ADR for one day
Range("A4:AF7").Select
Selection.delete Shift:=xlToLeft
Range("K4:AD7").Select
Selection.delete Shift:=xlToLeft
Range("AE4:DO7").Select
Selection.delete Shift:=xlToLeft
Range("AF4:AT7").Select
Selection.delete Shift:=xlToLeft
Range("AH4:CE7").Select
Selection.delete Shift:=xlToLeft
Columns("AE:AG").Select
Selection.Cut
Columns("C:C").Select
Selection.INSERT Shift:=xlToRight
Columns("F:M").Select
Selection.INSERT Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Windows("YORYK Daily Report " & DateStringFS & "$.xlsb").Activate
Sheets("Actual data").Activate
Columns("A:A").Select
Selection.NumberFormat = "m/d/yyyy"
Range("G4").Select
ActiveCell.FormulaR1C1 = "Rms"
Range("H4").Select
ActiveCell.FormulaR1C1 = "G Rms"
Range("I4").Select
ActiveCell.FormulaR1C1 = "Rm Rev"
Range("J4").Select
ActiveCell.FormulaR1C1 = "ADR"
Range("K4").Select
ActiveCell.FormulaR1C1 = "OOO Rms"
Range("L4").Select
ActiveCell.FormulaR1C1 = "Total Rev"
Range("G5").Select
ActiveCell.FormulaR1C1 = "=RC[-4]+RC[-3]"
Range("I5").Select
ActiveCell.FormulaR1C1 = "=RC[-7]-RC[13]"
Range("J5").Select
ActiveCell.FormulaR1C1 = "=RC[-1]/RC[-3]"
Range("K5").Select
ActiveCell.FormulaR1C1 = "=RC[-6]"
Range("L5").Select
ActiveCell.FormulaR1C1 = "=SUM(RC[-10],RC[2]:RC[9])-SUM(RC[10]:RC[29])"
'Colour titles for each title to mark that its done, for one day.
Range("G4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Rms"
Range("H4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "G Rms"
Range("I4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Rm Rev"
Range("J4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "ADR"
Range("K4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "OOO Rms"
Range("L4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "Total Rev"
Range("G4:L4").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0
.PatternTintAndShade = 0
End With
' End If for -1 day vs - 3 day.
End If
'Turn on screen updating and displaying alerts again (outside the loop).
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
The answer to your question is Yes, you should probably change your code to to work down the list of dates so that it is being driven by the data. In addition, your code could benefit a lot from better use of vba which you can learn:
As noted in comments, use variables in your vba code to give access workbooks, worksheets and cell ranges instead of using Activate and Select - which should be used only if you need to change what the user sees and, even then, only right at the end of your processing, just before giving control back to the user. Your code will be easier to read and run much faster.
Use named formatting styles instead of hard-coding styles. This is much more meaningful and is much easier to change and extend if you want to improve the appearance of your workbook without having to change the vba code.
Divide the code up into functions that do a specific parts of the logic, and call the functions instead of repeating the code. If you use variables to refer to workbooks, worksheets etc, then you can pass variables to the functions. For example, the code that processes one csv file could be written as a function that is called from higher-level logic.
I think you will find that your code becomes a lot simpler and easier to read and understand.
Please, try the next code. It is not tested, of course, but its logic should be correctly applied. It opens each csv file and copy its second row to the report starting from the 7th row, backwards to the first row:
Sub tes7DaysBackArray()
Dim arr7D, arrM, arrY, d As Date, DateStringFS As String, wsAD As Worksheet, wbLoc As Workbook, AlteryxFP As String
Dim pathRoot As String, fileName As String, comp As String, ws As Worksheet, i As Long, iRow As Long
DateStringFS = Format((Date), "dd.mm.yy"): d = Date: iRow = 7
'build arrays containing the necessary formatted strinns:
arr7D = Application.Transpose(Evaluate("TEXT(DATE(" & Year(d - 7) & "," & month(d - 7) & ",row(" & Day(d - 7) & ":" & Day(d - 1) & ")),""dd-mm-yyyy"")"))
arrM = Application.Transpose(Evaluate("TEXT(DATE(" & Year(d - 7) & "," & month(d - 7) & ",row(" & Day(d - 7) & ":" & Day(d - 1) & ")),""mmm yyy"")"))
arrY = Application.Transpose(Evaluate("TEXT(DATE(" & Year(d - 7) & "," & month(d - 7) & ",row(" & Day(d - 7) & ":" & Day(d - 1) & ")),""yyyy"")"))
Debug.Print Join(arr7D, "|"): Debug.Print Join(arrM, "|"): Debug.Print Join(arrY, "|") 'just to visually see the above built arrays...
If Environ("username") = "SP" Then
AlteryxFP = "Alteryx Output\"
Else
AlteryxFP = ""
End If
pathRoot = "C:\Users\" & comp & "\Dropbox (SHG)\" & AlteryxFP & "\Daily Finance & Revenue Data\1. Daily Occupancy Output\Site 5\"
Set wsAD = Workbooks("YORYK Daily Report " & DateStringFS & "$.xlsb").Sheets("Actual data")
For i = 0 To UBound(arr7D)
fileName = pathRoot & arrY(i) & "\" & arrM(i) & "\" & arr7D(i) & "\"
fileName = dir(fileName & "*manager*.csv")
If fileName <> "" Then
Set wbLoc = Workbooks.Open(Directory & fileName, local:=True)
Set ws = wbLoc.Sheets(1) 'the single existing sheet
If CStr(Format(ws.Range("AG2").Value, "dd-mm-yyyy")) = arr7D(i) Then
wsAD.rows(iRow & ":" & iRow).Value = ws.rows("2:2").Value: iRow = iRow + 1
wbLoc.Close False
Else
MsgBox "Date in file does not match " & arr7D(i)
End If
Else
MsgBox "No any required csv file could be found in & """ & fileName & """."
End If
Next i
End Sub
#Modifying Question for better understanding and how do i want the result is.
Wizhi answer almost matched for my question !! But need some more
changes in his answer because which code is not working for me !! And
no need to work based on GCN Date as he answered. The split work
done based on Destination Pincode .
Please help someone help me to Macro Code for Split data into multiple sheet within an excel workbook based on a table format. Below is the explanation of how i have done as per my knowledge and what is my expectation is !!
"Here is the workbooks what i have Done"
Please download the Macro_Folder and Unzip it in you "C" Drive.
Open Macro Workbook and Press Button to run macro.
If it asked for updating formulas as shown in below picture please select "Don't Update" to continue macro.
My Macro workbook view :
I Have done button option to Run the split macro in separate excel workbook.
Where the files Located
When self open and run Macro from Macro Workbook it automatically opens my XD MIS Report and start formatting and split the date into multiple sheets.
View of XD MIS is "Master Data" which is having overall raw data.
Here is the view after self Run Macro fro split Master data.
Code that i Used For Split Data into Multiple Sheet:
Sub Spli_Data()
Dim wb As Workbook
Dim myfilename As String
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
myfilename = "C:\Macro\XD MIS Report.xlsx"
Set wb = Workbooks.Open(myfilename)
Cells.Select
Selection.EntireColumn.Hidden = False
Selection.EntireRow.Hidden = False
Columns("B:F").Select
Range("B2").Activate
Selection.Delete Shift:=xlToLeft
Columns("D:E").Select
Range("D2").Activate
Selection.Delete Shift:=xlToLeft
Columns("H:H").Select
Range("H2").Activate
Selection.Delete Shift:=xlToLeft
Columns("K:L").Select
Range("K2").Activate
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
Columns("D:D").Select
Range("D2").Activate
Selection.Cut
Selection.End(xlToRight).Select
Columns("K:K").Select
Range("K2").Activate
Selection.Insert Shift:=xlToRight
Selection.End(xlUp).Select
Range("K1").Select
ActiveCell.FormulaR1C1 = "Remarks"
Columns("J:J").Select
Selection.Copy
Columns("K:K").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Columns("H:H").Select
Selection.Insert Shift:=xlToRight
Range("H1").Select
ActiveCell.FormulaR1C1 = "Packing Type"
Range("H1").Select
Selection.End(xlToLeft).Select
Cells.Select
Selection.FormatConditions.Delete
Columns("B:B").Select
Selection.Copy
Columns("A:A").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("A2").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=COUNTIF(R[-1]C[6]:RC[6],RC[6])"
Range("A2").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(R1C7:RC[6],RC[6])"
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.FillDown
Selection.End(xlUp).Select
Columns("A:A").Select
Range("A2").Activate
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A2").Select
Application.CutCopyMode = False
Range("A1:L3100").Select
Range("A2").Activate
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection
.VerticalAlignment = xlBottom
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
End With
With Selection
.VerticalAlignment = xlCenter
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
End With
With Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlCenter
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
End With
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
End With
With Selection.Font
.Name = "Calibri"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.TintAndShade = 0
End With
With Selection.Font
.Name = "Calibri Light"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.TintAndShade = 0
.ThemeFont = xlThemeFontMajor
End With
Range("A2").Select
Application.ScreenUpdating = False
vcol = Application.InputBox(prompt:="Which column would you like to filter by?", title:="Filter column", Default:="3", Type:=1)
Set ws = ActiveSheet
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Next
ws.AutoFilterMode = False
ws.Activate
Application.ScreenUpdating = True
End Sub
Result Of Split Data What i have right now:
Destination 1
Destination 2
Now Let's Clear About My Requirement:
I have done macro for format and Split Data into multiple Sheet,But this the not exact format result which i'm looking for.
The split should be done in same method but for result format should be like below formats based on macro code.
The split data should be in Multiple sheets of within an Excel Workbook . Not split to multiple workbooks !!
Write a macro for split Data in this format for all Destination Pincode:
This how i'm expecting final result through macro code
Expected Format of #Destination 1 Sample After Split done
#Destination 1 Sample
This is an examples of what i'm looking for. The same have to done
for all destination which is in Master Data
Hope !! now my question is clear for better understanding and easy to answer.
Updated code:
#Mark Balhoff, Thanks for your valuable input, I always like to learn and get feedback to improve myself :). I have used your input in the code and also extended it a bit.
This code is using dictionary so you need to activate "Microsoft Scripting Runtime"
"Tools" -> "References" -> "Microsoft Scripting Runtime" to make dictionary work
User process to split Master Data:
I assume that the user will split this data in the picture:
Pressing the button, it will choose column 7.
(My opinion is that this part with InputBox etc... is unnecessary as you always want to filter by column 7 regardless, so I feel it confused the end user)
Is quite unclear from what "raw data" you start with as new pictures/data have appeared in the updated question. I have assumed that the data that we should split looks like this, as it was stated first
Output of the first unique Destination Pincode:
Output of the second unique Destination Pincode:
Code:
Option Explicit
Sub Split()
Dim lr As Long
Dim lc As Long
Dim ws As Worksheet
Dim ws_new As Worksheet
Dim DestPincode As Range
Dim DestPincodeCol As Long
Dim vcol As Long
Dim vcol_value As String
Dim vcol_name As String
Dim vcol_prompt As String
Dim i As Integer
Dim DestPincode_ws_new As Range
Dim DestPincodeCol_ws_new As Long
Dim DestPincodeRow_ws_new As Long
Application.ScreenUpdating = False
'##### SETTINGS #####
Set ws = ActiveWorkbook.Worksheets("Master_Data") 'Set master data sheet
Set DestPincode = ws.Range(ws.Cells(1, 1), ws.Cells(1, ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column)).Find(What:="Destination Pincode", LookIn:=xlValues, LookAt:=xlWhole) 'Set name to search after, i.e. Destination
'####################
lc = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column 'Find last column in Master Data
DestPincodeCol = DestPincode.Column 'Get column number for Destination Pincode
lr = ws.Cells(ws.Rows.Count, DestPincodeCol).End(xlUp).Row 'Get last row
'This macro splits data into multiple worksheets based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like to filter by, and it just creates these worksheets.
'##### Filter based on InputBox #####
vcol = Application.InputBox(prompt:="Which column would you like to filter by?", title:="Filter column", Default:="7", Type:=1)
If vcol <> 7 Then Exit Sub
'##### Get all the uniqe "Destination Pincodes" #####
' You need to activate "Tools" -> "References" -> "Microsoft Scripting Runtime" to make dictionary work
Dim DestPincodeData()
Dim UniqueDestPincodeData As Object
Dim DestPinRow As Long
Set UniqueDestPincodeData = CreateObject("Scripting.Dictionary")
DestPincodeData = Application.Transpose(ws.Range(ws.Cells(1, DestPincodeCol), ws.Cells(ws.Cells(Rows.Count, DestPincodeCol).End(xlUp).Row, DestPincodeCol))) 'Get all the Destination Pincode values
For DestPinRow = 2 To UBound(DestPincodeData, 1) 'Start from row 2 (to skip header) and add unique values to the dictionary
UniqueDestPincodeData(DestPincodeData(DestPinRow)) = 1 'Add value to dictionary
Next
'##### Loop through all the unqie Destination Pincodes and add to seperate workbooks #####
Dim new_wb As Workbook
Set new_wb = Application.Workbooks.Add 'Add new workbook
'Set new_wb = ActiveWorkbook
Dim DestPincodeName As Variant
Dim MyRangeFilter As Range
Set MyRangeFilter = ws.Range(ws.Cells(1, 1), ws.Cells(lr, lc)) 'Filter range 'Set filter range
For Each DestPincodeName In UniqueDestPincodeData.Keys 'Filter through all the unique names in dictionary "UniqueDestPincodeData"
'Debug.Print "Destination Pincode: " & DestPincodeName 'Print current unique Destination Pincode name
'Filter the data based on "Destination Pincode" and Column from InputBox
With MyRangeFilter
.AutoFilter Field:=DestPincodeCol, Criteria1:=DestPincodeName, Operator:=xlFilterValues 'Filter on Destination Pincode
End With
'##### Create new workbook for the filtered data #####
'To add to new worksheet:
Sheets.Add(After:=Sheets(Sheets.Count)).Name = DestPincodeName
Set ws_new = new_wb.Worksheets(DestPincodeName)
'##### Create template in the new workbook #####
'Building template output, row by row
ws_new.Range("A1:A7").Value = WorksheetFunction.Transpose( _
Array("*******", "TRIP NO", "TRIP DATE/TIME", "TRUCKTYPE (OWN/ATT/ADHOC)", "SEAL #", "SUPERVISOR NAME", "REMARK"))
ws_new.Range("H2:H6").Value = WorksheetFunction.Transpose( _
Array("VEHICLE NO", "VEHICLE CAPACITY", "DRIVER NAME", "DRIVER NO", "VENDOR NAME"))
Dim Top_Area_Cell_Format As Range
Set Top_Area_Cell_Format = ws_new.Range("A1:L1,A7:L7,A2:D2,E2:G2,H2:I2,J2:L2," _
& "A3:D3,E3:G3,H3:I3,J3:L3,A4:D4,E4:G4,H4:I4," _
& "J4:L4,A5:D5,E5:G5,H5:I5,J5:L5,A6:D6,E6:G6,H6:I6,J6:L6")
Application.DisplayAlerts = False
Top_Area_Cell_Format.Merge 'Merge cells
Top_Area_Cell_Format.HorizontalAlignment = xlLeft 'Make title in center
Top_Area_Cell_Format.Borders.LineStyle = xlContinuous 'Add border lines
Top_Area_Cell_Format.Font.Bold = True 'Add Bold text
ws_new.Range("A1:L1").HorizontalAlignment = xlCenter 'Make title in center
Application.DisplayAlerts = True
'##### Paste filtered data from Master_Data sheet #####
ws.Range(ws.Cells(1, 1), ws.Cells(lr, lc)).SpecialCells(xlCellTypeVisible).HorizontalAlignment = xlCenter 'Make text in center
ws.Range(ws.Cells(1, 1), ws.Cells(lr, lc)).SpecialCells(xlCellTypeVisible).EntireRow.Copy 'Copy entire row from filtered data
ws_new.Cells(8, "A").PasteSpecial xlPasteAll 'Paste all values including formats
Set DestPincode_ws_new = ws_new.Range(ws_new.Cells(8, 1), ws_new.Cells(1, ws_new.Cells(8, ws_new.Columns.Count).End(xlToLeft).Column)).Find(What:="Destination Pincode", LookIn:=xlValues, LookAt:=xlWhole) 'Set name to search after, i.e. Destination
DestPincodeCol_ws_new = DestPincode_ws_new.Column
DestPincodeRow_ws_new = ws_new.Cells(ws_new.Rows.Count, DestPincodeCol_ws_new).End(xlUp).Row
'Add total
ws_new.Cells(DestPincodeRow_ws_new + 1, "A").Value = "TOTAL"
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "A"), ws_new.Cells(DestPincodeRow_ws_new + 1, "G")).Merge 'Merge cells
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "A"), ws_new.Cells(DestPincodeRow_ws_new + 1, "G")).HorizontalAlignment = xlCenter 'Make text in center
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "A"), ws_new.Cells(DestPincodeRow_ws_new + 1, "G")).Borders.LineStyle = xlContinuous 'Add border lines
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "A"), ws_new.Cells(DestPincodeRow_ws_new + 1, "G")).Font.Bold = True 'Add Bold text
'Add total values
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "I"), ws_new.Cells(DestPincodeRow_ws_new + 1, "I")).Formula = "=SUM(I9:I" & DestPincodeRow_ws_new & ")" 'Add sum for "No. of cartons"
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "J"), ws_new.Cells(DestPincodeRow_ws_new + 1, "J")).Formula = "=SUM(J9:J" & DestPincodeRow_ws_new & ")" 'Add sum for "Actual weights"
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "H"), ws_new.Cells(DestPincodeRow_ws_new + 1, "L")).Borders.LineStyle = xlContinuous 'Add border lines
ws_new.Range(ws_new.Cells(DestPincodeRow_ws_new + 1, "H"), ws_new.Cells(DestPincodeRow_ws_new + 1, "L")).Font.Bold = True 'Add Bold text
'##### Add sign boxes #####
Dim Bottom_Area_Cell_Text_Rng As String
Dim Bottom_Area_Cell_Format As String
Dim Bottom_Area_Cell_Format_rng As Range
Bottom_Area_Cell_Text_Rng = "B" & DestPincodeRow_ws_new + 2 & ":H" & DestPincodeRow_ws_new + 2
ws_new.Range(Bottom_Area_Cell_Text_Rng).Value = Array("Driver Signature", "", "Incharge Signature", "", "Security Signature", "", "REMARK")
Bottom_Area_Cell_Format = "A" & DestPincodeRow_ws_new + 2 & ":A" & DestPincodeRow_ws_new + 4 & "," _
& "B" & DestPincodeRow_ws_new + 2 & ":C" & DestPincodeRow_ws_new + 4 & "," _
& "D" & DestPincodeRow_ws_new + 2 & ":E" & DestPincodeRow_ws_new + 4 & "," _
& "F" & DestPincodeRow_ws_new + 2 & ":G" & DestPincodeRow_ws_new + 4 & "," _
& "H" & DestPincodeRow_ws_new + 2 & ":L" & DestPincodeRow_ws_new + 4
Set Bottom_Area_Cell_Format_rng = ws_new.Range(Bottom_Area_Cell_Format)
Application.DisplayAlerts = False
Bottom_Area_Cell_Format_rng.Merge 'Merge cells
Bottom_Area_Cell_Format_rng.HorizontalAlignment = xlLeft 'Make title in center
Bottom_Area_Cell_Format_rng.Borders.LineStyle = xlContinuous 'Add border lines
Bottom_Area_Cell_Format_rng.VerticalAlignment = xlTop 'Alignment of text
Bottom_Area_Cell_Format_rng.Font.Bold = True 'Add Bold text
Application.DisplayAlerts = True
'Adjust Column width
ws_new.Columns("A:L").Select
Selection.EntireColumn.AutoFit
Set ws_new = Nothing 'Reset worksheet value
Next
Application.DisplayAlerts = False
new_wb.Worksheets(1).Delete
Application.DisplayAlerts = True
On Error Resume Next
Sheet1.ShowAllData 'remove filter
On Error GoTo 0
ws.AutoFilterMode = False
Application.ScreenUpdating = True
End Sub
Link to workbook:
https://www.dropbox.com/s/86wlv99y6wylpn8/split%20data.xlsm?dl=0
I'm not sure If I've understand properly, but it looks like you want to split your data depending on the value of PINCODE column.
Besides, your question is too broad right now, you should focus more.
So, as example, I understand you would select all rows containing PINCODE=PUZHAL, and copy all of them into a different workbook.
And you want this for each unique PINCODE.
I made a fake dataset coloring rows, and I split the data into new workbooks. You'll need to adapt this to paste the data into existing workbooks (or new worksheets of same workbook, whatever)
My data is like this:
My code:
Sub TEST()
Application.ScreenUpdating = False
Dim MyDict As Object
Dim i As Long
Dim MyKey As Variant
Dim LR As Long
Dim WB As Workbook
Dim MyRows As Variant
LR = Range("G" & Rows.Count).End(xlUp).Row
Set MyDict = CreateObject("Scripting.Dictionary")
For i = 2 To LR Step 1
If MyDict.Exists(Range("G" & i).Value) = False Then
'we create the PINCODE in Dictionary and assign row number
MyDict.Add Range("G" & i).Value, i
Else
'PINCODE already in Dictionary, we add the new row number
MyDict(Range("G" & i).Value) = MyDict(Range("G" & i).Value) & "|" & i
End If
Next i
'now Dictionary holds all pincodes and all row numbers for each pincode.
'we create a workbook for each PINCODE, but you can adapt this to open a exact workbook depending on PINCODE
'I'm copying the rows starting at row 1, but you can adapt this to your model for sure
For Each MyKey In MyDict.Keys
Set WB = Application.Workbooks.Add
LR = 1 'change this to starting row
MyRows = Split(MyDict(MyKey), "|") 'we create array of rows numbers
For i = LBound(MyRows) To UBound(MyRows) Step 1
'we copy range A:L from that row into destiny workbook
ThisWorkbook.ActiveSheet.Range("A" & MyRows(i) & ":L" & MyRows(i)).Copy WB.ActiveSheet.Range("A" & LR & ":L" & LR)
LR = LR + 1 'we increase LR so next data will be pasted into next row
Next i
Erase MyRows
Set WB = Nothing
DoEvents
Next MyKey
MyDict.RemoveAll
Set MyDict = Nothing
Application.ScreenUpdating = True
End Sub
And this is how i get all my data splitted into different files depending on PINCODE.
I suggest You create a Pivot Table.
By that Pivot table you create a code to extract data on a pivotable base on a list and transfer that to the formatted workbook you created and make a loop until the last Destination Pincode. I also use Excel VBA Form to Trigger this. I can make you one if you post your Excel here.
I've created a macro that transfers the selected value from the dropdown list to the sheet with the same name as the value. I recommend that you review it.
Source : Split data into multiple sheets
I am very new to the world of Excel VBA World, I am currently working on merging multiple worksheets from different .csv files (same folder) into one giant .csv file.
Previously, I have already ran a code (successfully) to select all the data I wanted to all the .csv files in that folder. But I can't seem to merge all the sheets from these files into one....
This is the successful code
Option Explicit
Sub LoopThroughFiles()
Dim xFd As FileDialog
Dim xFdItem As Variant
Dim xFileName As String
Set xFd = Application.FileDialog(msoFileDialogFolderPicker)
If xFd.Show = -1 Then
xFdItem = xFd.SelectedItems(1) & Application.PathSeparator
xFileName = Dir(xFdItem & "*.csv*")
Do While xFileName <> ""
With Workbooks.Open(xFdItem & xFileName)
'your code here
OP10SelectCut
End With
xFileName = Dir
Loop
End If
End Sub
Sub OP10SelectCut()
'
' OP10SelectCut 巨集
'
'
Dim TotalRow As Integer
TotalRow = Range("B1").End(xlDown).Row
Columns("B:B").Select
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlNotBetween, _
Formula1:="=-0.02", Formula2:="=0.02"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
End With
Selection.FormatConditions(1).StopIfTrue = False
Selection.AutoFilter
ActiveSheet.Range("$B$1:$B$" & TotalRow).AutoFilter Field:=1, Criteria1:=RGB(255 _
, 255, 0), Operator:=xlFilterCellColor
Columns("B:C").Select
Selection.Copy
Sheets.Add After:=ActiveSheet
Range("A1").Select
ActiveSheet.Paste
End Sub
This is the not working code
'合併多個Excel檔案
Sub GetSheets()
Path = "C:\Users\andrew-wu\Desktop\OP10TestBatch"
Filename = Dir(Path & "*.csv*")
Do While Filename <> "*.csv*"
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
'只複製第一個Sheet
If ActiveWorkbook.Sheets.Count > 0 Then
ActiveWorkbook.Sheets(1).Copy _
After:=ThisWorkbook.Sheets(1)
'每個Sheet都複製
'For Each Sheet In ActiveWorkbook.Sheets
'Sheet.Copy After:=ThisWorkbook.Sheets(1)
'Next Sheet
End If
Workbooks(Filename).Close
Filename = Dir()
Loop
End Sub
I saved this file as a “Formatted Text (Space delimited)”. When I open it using excel the content in cell F7 is moved over to D7. Please see the attachment. Would I have to add “space saving” text to a7, b7, d7, & e7 or is there another way of doing this ?
Saved space delimited file:
enter image description here:
Sub Macro1()
'
' Main Macro
'
' Keyboard Shortcut: Ctrl+Shift+P
'
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+Shift+P
'
Range("C7").Select
ActiveCell.FormulaR1C1 = "ENTER_FAILURE"
Range("F7").Select
ActiveCell.FormulaR1C1 = "1"
Range("G7").Select
ActiveCell.FormulaR1C1 = "2"
Range("H7").Select
ActiveCell.FormulaR1C1 = "3"
Range("I7").Select
ActiveCell.FormulaR1C1 = "4"
Range("G7:I7").Select
Selection.AutoFill Destination:=Range("G7:O7"), Type:=xlFillDefault
Range("G7:O7").Select
Dim n As Integer
Dim colmm As Integer
Dim origFILEname As String: origFILEname = ActiveSheet.Name
Dim newName As String: newName = origFILEname & " + " & CStr(0)
Dim tstCaseCount As Double: tstCaseCount = 0
For colmm = 4 To 12 Step 1
' Copy orginal sheet and make copy active sheet
Call CopySheetAndRename(origFILEname, newName)
'innter loop will deal with inputting failures
For n = 36 To 56 Step 1
ActiveSheet.Cells(n, colmm) = 8888
Next n
'add code that save txt file here
SaveToRelativePath
'Increment test case count
tstCaseCount = tstCaseCount + 1
newName = origFILEnMAE & " + " & CStr(tstCaseCount)
Next colmm
End Sub
Sub CopySheetAndRename(xOrignalFileName As String, NwName As String)
'create a new sheet and rename it
Sheets(xOrignalFileName).Copy after:=Sheets(1)
On Error Resume Next
ActiveSheet.Name = NwName
End Sub
Sub SaveToRelativePath()
Dim relativePATH As String
'make failure red sub
MkFailureRed
'save ffile name as space delimited (*.prn) in the current folder
relativePATH = ThisWorkbook.Path & "\" & ActiveSheet.Name & ".prn"
ActiveWorkbook.SaveAs Filename:=relativePATH, FileFormat:=xlTextPrinter, CreateBackup:=False
'save file name as workbook
relativePATH = ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsx"
ActiveWorkbook.SaveAs Filename:=relativePATH, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
End Sub
Sub MkFailureRed()
'add after to make index number red
With Selection.Font
.Color = -16776961
.TintAndShade = 0
End With
'make all the failure red
ActiveWindow.SmallScroll down:=-3
Range("D12").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
ActiveWindow.SmallScroll down:=-93
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=-50"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
I have a excel sheet with a sale offer for multiple receivers each day.
The file has two tabs, Now I created a macro, to send the emails automatic.
The macro has a sub for each day.
Now one of the tabs is copied to a new worksheet than it changes one cell which has the name of the receiver in it.
After that, it sends the mail through outlook.
The sub begins with:
' Copy tab to a new worksheet
Sheets("Offer").Select
Sheets("Offer").Copy
Cells.Select
' Copy worksheet with only results to replace formulas
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Change the color for cell A15:C15
Range("A15:C15").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 14336204
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'Format the numbers to 2 numbers after the comma
Range("D20:D47").Select
Selection.NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* ""-""??_);_(#_)"
' Turn alerts off
Application.DisplayAlerts = False
' Set the author
ActiveWorkbook.BuiltinDocumentProperties("Author") = "Author name"
Then for each receiver, I have a block like this:
' email1
Range("D15:H15").Select
ActiveCell.FormulaR1C1 = "name1"
ActiveWorkbook.SaveAs Filename:= _
"C:\Aanbod\Vrijdag\Filename_receivername1", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
'send mail
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = "receiver1#domain.com"
.CC = ""
.BCC = ""
.Subject = "subject here"
.Body = ""
.Attachments.Add ActiveWorkbook.FullName
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
And to end the sub:
' Turn alerts back on
Application.DisplayAlerts = True
' Close active window
ActiveWindow.Close
' Go to tab1
Sheets("tab1").Select
Now, this is working, but not really efficient. Also for some reason, it's not working entirely on one of the computers we use it on.
On that computer, it skips some of the receivers, so it doesn't send all emails.
Now I like to create an 3rd tab in the sales offer worksheet, with the email addresses in it, including the names of the receivers.
How can I do this?
So I rebuild the code now, so it uses a loop for generating the files and sending the mails.
This is what I got now:
Sub Maakbestanden_maandag()
Dim Sh As Worksheet
Set Sh = ThisWorkbook.Sheets("Kopers-Maandag")
Dim Ab As Worksheet
Set Ab = ThisWorkbook.Sheets("Aanbod")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Sheets("Aanbod").Select
Sheets("Aanbod").Copy
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A15:C15").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 14336204
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range("D20:D49").Select
Selection.NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* ""-""??_);_(#_)"
Range("C20:C49").Select
Selection.NumberFormat = "#"
Range("E20:F49").Select
Selection.NumberFormat = "0"
Columns("E:E").ColumnWidth = 8
Columns("F:F").ColumnWidth = 6
ActiveWorkbook.BuiltinDocumentProperties("Author") = "AUTHOR NAME"
Range("G50").Select
ActiveCell.FormulaR1C1 = "=SUM(R[-30]C:R[-1]C)"
Range("G51").Select
ActiveCell.FormulaR1C1 = "=R[-1]C/12"
Dim i As Integer
Dim last_row As Long
last_row = Application.WorksheetFunction.CountA(Sh.Range("A:A"))
For i = 2 To last_row
Range("D15:H15").Select
ActiveCell.FormulaR1C1 = Sh.Range("B" & i).Value
Range("D15:H15").Select
Application.ActiveWorkbook.SaveAs Filename:=Sh.Range("C" & i).Value, _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Next i
Application.DisplayAlerts = True
ActiveWindow.Close
MsgBox "Bestanden aangemaakt"
Call Verstuuremail_maandag
End Sub
and than to send the actual mails:
Sub Verstuuremail_maandag()
Dim Sh As Worksheet
Set Sh = ThisWorkbook.Sheets("Kopers-Maandag")
Dim OA As Object
Dim msg As Object
Set OA = CreateObject("Outlook.Application")
Dim i As Integer
Dim last_row As Long
last_row = Application.WorksheetFunction.CountA(Sh.Range("A:A"))
For i = 2 To last_row
Set msg = OA.createitem(0)
msg.To = Sh.Range("A" & i).Value
msg.Subject = "Sales offer"
msg.body = ""
If Sh.Range("C" & i).Value <> "" Then
msg.attachments.Add Sh.Range("C" & i).Value
End If
DoEvents
msg.send
Next i
MsgBox "E-mails voor maandag verstuurd"
Sheets("Veilprijzen").Select
End Sub
Now when I'm testing it, it works well, but still sometimes it stops at 2/3 of the way while sending the mails (generating the files works fully everytime).
When it stops, it's trowing the following error:
vba error 5 invalid procedure call or argument
VBA marks it at: msg.send
It's odd, sometimes we get a full run on the same day, with the very same code and customer information, and sometimes it doesn't go all the way.
Any recommendation to solve this?