I need an excel macro to export data based on variable - excel

I have a spreadsheet that exports saved invoices. the export works perfectly. however, i want to ONLY export data for the previous week. the last cell in the workbook has the last saved date in it. i want to search through the column to find the last saved date within the previous 7 days, and create an export csv file with just that data.
here is what i have so far.
Sub CopyToCSV()
Dim MyPath As String
Dim MyFileName As String
Dim Region As Variant
Application.ScreenUpdating = False
Sheets("Invoice").Activate
Region = Range("E5").Value
Sheets("Stored Invoices").Activate
MyPath = Application.ActiveWorkbook.Path
MyFileName = "Region" & Region & "-" & Format(Date, "ddmmyy")
'Makes sure the path name ends with "\":
MyPath = MyPath & "\"
'Makes sure the filename ends with ".csv"
MyFileName = MyFileName & ".csv"
'Copies the sheet to a new workbook:
Sheets("Stored Invoices").Copy
'The new workbook becomes Activeworkbook:
With ActiveWorkbook
'Saves the new workbook to given folder / filename:
'MyPath &
.SaveAs Filename:=MyPath & MyFileName, FileFormat:=xlCSV, CreateBackup:=False
'Closes the file
.Close False
End With
End Sub
any help would be greatly appreciated!
Becky

Assuming the data is in order:
Loop through each cell in the column containing the date, and evaluate said date. Have it loop until it encounters a date more than 7 days before the current data. Have a counter in the loop that counts how many rows it looped though. then, its simply Range("A1", Cells(countedrows, Numcolumns)).copy DestinationRange assuming the data starts in a1, so the range would be from A1 down to the last counted row in the last column, and then you move that to a new Sheet/book, and save that
there be the logic, Edit your post with your new code and comment if you get stuck
HTH

Related

How to make folder path universal?

New to VBA and have an assignment to create a sub that pastes from one workbook into a new workbook. A requirement for saving the file is that "the folder path be universal so other people can create this folder too". What amendment would I make to the ActiveWorkbook.SaveAs method to fulfill this? Thanks
Sub pasteTable()
Dim formatting As Variant 'create variable to hold formatting2 workbook path
formatting = Application.GetOpenFilename() 'user is prompted and selects path to formatting2 workbook and assigns to formatting variable
Workbooks.Open formatting 'formatting2 workbook is now active
Worksheets("Formatting").Range("B3:R13").Copy 'copies table from formatting2 workbook
Workbooks.Add 'add new workbook
Worksheets(1).Range("B3:R13").Select 'selects range on worksheet of new workbook to paste table
Selection.PasteSpecial xlPasteAll 'pastes table
Columns("B:R").ColumnWidth = 20 'ensures table has proper row and column heights/widths
Rows("3:13").RowHeight = 25
Worksheets(1).Name = "Table Data" 'renames worksheet
ActiveWorkbook.SaveAs "C:\Users\name\Desktop\names Excel Assessment VBA\names Excel Assessment VBA " & Format(Date, "dd/mmm/yyyy"), FileFormat:=xlOpenXMLWorkbookMacroEnabled
'saves workbook according to desired specifications
End Sub
Change your Save line to this:
ActiveWorkbook.SaveAs "C:\Users\" & Environ("Username") & "\Desktop\Excel Assessment VBA\Excel Assessment VBA " & Format(Date, "dd-mmm-yyyy") & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled
The Username system variable will adjust depending on the Windows account that is in use. Just make sure each user has those folders existing on their desktop too, or you will get an error. I also removed names from the folder names as i assume you were trying to do something with the username there as well. You can adjust that to your needs.
Your Date format needed to change too as it was including illegal characters.
You also forgot to include a file extension, so I added that as well.
There is a lot going on with that line, including a lot of mistakes, so you are going to have to play with it a bit until you get exactly what you need. You may want to simplify it a bit until you get the hang of all those things.
I think you have to add some more checks
The script expects the name of the tool-path-folder as constant ToolFolder.
Plus a second constant ToolBaseFolder that could be set to the parent-path `ToolFolder, e.g. a network path. If the const is empty, users desktop will be used.
If this path does not yet exist it will be created.
Option Explicit
Private Const ToolBaseFolder As String = "" 'if ToolBaseFolder is an empty string desktop will be used instead
Private Const ToolFolder As String = "MyNameForToolFolder"
Public Sub testWbToToolFolder()
'this is just for testing
Dim wb As Workbook: Set wb = ActiveWorkbook
saveWbToToolFolder wb, "test.xlsx"
End Sub
Public Sub saveWbToToolFolder(wb As Workbook, filename As String)
'you don't need this sub - but have the same code line in your main routine
wb.SaveAs getToolFolder & filename
End Sub
Public Function getToolFolder() As String
'this returns the toolfolder e.g. C:\Users\xyz\Desktop\MyNameForToolFolder
Dim basepath As String
basepath = ToolBaseFolder & "\"
If existsFolder(basepath) = False Then
If LenB(ToolBaseFolder) > 0 Then
MsgBox ToolBaseFolder & " does not exist." & vbCrLf & _
"File will be saved to " & ToolFolder & " on desktop ", vbExclamation
End If
basepath = getDesktopFolderOfUser
End If
Dim fullpath As String
fullpath = basepath & ToolFolder & "\"
If existsFolder(fullpath) = False Then
makeFolder fullpath
End If
getToolFolder = fullpath
End Function
Private Function existsFolder(path As String) As Boolean
If Len(path) < 2 Then Exit Function 'can't be a valid folder
existsFolder = LenB(Dir(path, vbDirectory)) > 0
End Function
Private Function getDesktopFolderOfUser() As String
getDesktopFolderOfUser = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\"
End Function
Private Function makeFolder(path As String)
'https://stackoverflow.com/a/26934834/16578424 plus comment from rayzinnz
CreateObject("WScript.Shell").Run "cmd /c mkdir """ & path & """", 0, True
End Function

Save file path according to worker matric number vba

I would like to save file in a "CONSOLIDATE FOLDER". But the file path should depend on staff working number ID (00639) where they input it in the "TEMPLATE" worksheet cell "N3". And in case staff forgot to input their working ID, there'll be a pop up box telling them to fill in their ID.
Any help really appreciated.
Sub MergeFile ()
Dim WB As Workbook
Dim WS as Worksheet
Dim FileName as String
Dim FilePath as String
Set WB = Workbook.Add
FilePath = "C:\Users\KGA00639\Desktop\CONSOLIDATE FOLDER"
FileName = ThisWorkbook.Worksheets("TEMPLATE").Range("L15").Value
For Each WS in ThisWorkbook.Worksheets
If WS.Name <> "TEMPLATE" Then
WS.Copy before:=WB.Sheets(1)
End if
If FileName = "" Then
FileName = InputBox ("You did not name the workbook" & vbCrLf & _
"Please write the name and press OK.:,"Setting the workbook name")
If FileName = "" Then Exit sub
ThisWorkbook.Worksheets("TEMPLATE").Range("L15").Value = FileName
End If
Next
ActiveWorkbook.SaveAs FileName:=FilePath & "\" & FileName
MsgBox ("Done"!)
ActiveWorkbook.Close
End Sub
This solution should come rather close to what you want. Please take a look.
Sub MergeFile()
' 056
Dim Wb As Workbook
Dim Ws As Worksheet
Dim FileName As String
Dim FilePath As String
Dim UserID As String
With ThisWorkbook.Worksheets("TEMPLATE")
UserID = .Cells(1, "A").Value ' change address to suit
FileName = .Range("L15").Value
If Left(UserID, 2) <> "ID" Then
MsgBox "You must enter your valid user ID in" & vbCr & _
"cell A1 of the 'Template' tab." & vbCr & _
"This program will now be terminated.", _
vbInformation, "Incomplete preparation"
.Activate
.Cells(1, "A").Select ' change to match above
Exit Sub
End If
End With
Application.ScreenUpdating = False
' use the UserID variable in whichever way you wish
FilePath = Environ("UserProfile") & "\" & UserID & "\Desktop\CONSOLIDATE FOLDER"
Set Wb = Workbooks.Add
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "TEMPLATE" Then
Ws.Copy Before:=Wb.Sheets(1)
End If
Next Ws
Wb.SaveAs FilePath & FileName, xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
You didn't specify where on the 'Template' tab the user ID would be found. The above code looks for it in cell A1. That cell is mentioned in 3 locations in the code (once in the message text). Please modify the code to match your facts.
You also didn't say where the UserID should appear in the FilePath. I placed it before the Desktop. I'm sure you will know how to amend that bit of code to suit you better.
When saving the workbook my code specifies an xlsx format. If this isn't what you want change the file format constant in the SaveAs line. I didn't think it a good idea to specify the extension in the 'Template'. You may like to move it to the code.
Finally, you didn't specify the next step after creation of the new workbook. So the code ends in the middle of nowhere. Excel made the new workbook the active one but you may like to close it, or ThisWorkbook, and determine what to do with the blank worksheet(s) still contained in the new book. There are a lot of lose ends still to tidy up. Good luck!

Remove empty rows at the end of a csv file being saved using VBA

I am very new to VBA. I was trying to save a tab from an excel worksheet into a separate csv file using VBA and below is the code I used. However, the code creates a csv file but the file size is significantly large. For example, even if the worksheet has just three rows, the csv file created would be of 21 MB. The reason being, my excel worksheet is filled with formulas for a 1000 rows and 20 columns. Also the number of entries will vary. Therefore after the execution, the csv would have empty rows(output attached as image)enter image description here. I just want to modify the code so that the empty rows(only the entire empty rows across 20 columns) are deleted from the csv. Any help is much appreciated.
Code:
Sub CREATE_CSV()
Sheet6.Unprotect Password:="1000"
Dim MyPath As String
Dim MyFileName As String
MyPath = Application.ActiveWorkbook.Path
MyFileName = "Titles_Footnotes"
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
Sheets("Titles_Footnotes").Copy
ActiveSheet.Range("1:4").EntireRow.Delete
ActiveSheet.Range("U:Z").EntireColumn.Delete
Application.DisplayAlerts = True
With ActiveWorkbook
Dim URvalues
Dim usedRangeAddress As String
usedRangeAddress = ActiveSheet.UsedRange.Address
URvalues = ActiveSheet.UsedRange
ActiveSheet.Cells.Delete
Range(usedRangeAddress) = URvalues
.SaveAs Filename:=MyPath & MyFileName, FileFormat:=xlCSV,CreateBackup:=False
.Close False
End With
Application.DisplayAlerts = True
Sheet6.Protect Password:="1000", AllowFiltering:=True
MsgBox ("CSV Created!")
End Sub

Subscript out of range when copying range to another workbook

I am writing a reporting system where the user fills out a form and a form button runs a macro to save the file with a name based on several fields including a timestamp.
All the data is is also on a second sheet but in one row for ease of copying to a master sheet.
I am trying to to extend the save macro to copy this row to the last line of a second workbook.
This was successful when the macro was run from a separate workbook but I can't for the life of me work out how to do it from within the file itself.
I've triple checked the paths themselves, I know they're right as the new files are being created, I've run msgbox in the code to check the filename and the variable are the same too.
timestampedfile = Worksheets("single_line").Range("b3")
totalpath = Path & timestampedfile & ".xlsm"
ActiveWorkbook.SaveCopyAs filename:=totalpath
master_wb = "s:\blah\blah\blah.xlsx"
master_sht = "Master_Database"
contact_wb = totalpath
contact_sht = "single_line"
Workbooks.Open (master_wb)
Workbooks.Open (contact_wb)
MsgBox (totalpath)
Workbooks(contact_wb).Worksheets(contact_sht).Range("A3:AQ3").Copy Worksheets(master_wb).Sheets(master_sht).Range("A" & Rows.Count).End(xlUp)(2)
'
Both the Workbooks open so I know the paths are right, can anyone help?
Solution by OP
Solved thanks to comment about workbook variables by BigBen:
Use workbook variables, instead of referencing the workbook by name: Dim masterWb as Workbook, then Set masterWb = Workbooks.Open("s:\blah\blah\blah.xlsx" ). Similarly for the contact workbook. You might consider using worksheet variables too, instead of using sheet names.
Code changed to:
Dim master_wb As Workbook
Dim contact_wb As Workbook
Dim master_sht As Worksheet
Dim contact_sht As Worksheet
Path = "S:\blah\" & Worksheets("report").Range("c8") & "\"
filename = Worksheets("back_end_formulas").Range("e10")
timestampedfile = Worksheets("single_line").Range("b3")
totalpath = Path & timestampedfile & ".xlsm"
ActiveWorkbook.SaveCopyAs filename:=totalpath
SetAttr totalpath, vbReadOnly
Set master_wb = Workbooks.Open("S:\blah\Master_Database2.xlsx")
Set master_sht = master_wb.Sheets("Master_Database")
Set contact_wb = Workbooks.Open(totalpath)
Set contact_sht = contact_wb.Sheets("single_line")
ThisWorkbook.Activate
contact_sht.Range("A3:AQ3").Copy master_sht.Range("A" & Rows.Count).End(xlUp)(2)
master_wb.Close SaveChanges:=True
contact_wb.Close SaveChanges:=False
ActiveWorkbook.Close SaveChanges:=False

VBA looping through files that meet two criteria

Below is working code that is looping through files in a folder based on a user's search criteria. The folder will grow throughout the year to over 1000 files, so rather than looping through all of them every time the macro runs, I would like to add a second criteria that compares the time stamps on the files to a time stamp saved on the file as the last time it was run. LastUpdateDate is set up as variable in date format at the top of the module, and the old timestamp is saved to it at the beginning of the code.
I tried this but it left me with a run time error. Is this doable using Do While, or is there another format I need to be looking at? I also tried nesting the date comparison as an if statement under the Do While, but came up with other errors.
Do While FileName <> "" and FileDateTime(FileName) > LastUpdateDate
Working code from this section:
FileName = Dir(FolderName & "*" & MyCriterion & "*" & ".xl??")
'Loop through all matching files
Do While FileName <> ""
'Open the next matching workbook
Workbooks.Open (FolderName & FileName)
Sheets("Report Data").Select
'Call GrabTheData
GrabTheData
'Close the workbook
Workbooks(FileName).Close savechanges:=False
'Get the name of the next match in folder
FileName = Dir
Loop
End Sub
Two things:
FileDateTime
FileDateTime requires the full file path, not just the file name
Loops and Conditions
Do While (condition) stops execution of the block when (condition) is no longer true.
That is, it will stop execution as soon as (condition) is false. I don't believe this is the intended behavior.
Put an If (condition) block within the loop itself. This will loop through every workbook that matches MyCriterion, but only operate on those that match (condition).
Example (with recommendations)
Sub GrabAllData(ByVal FolderName As String, ByVal MyCriterion As String)
Dim FileName As String
Dim LastUpdateDate As Date
Dim wb As Workbook
LastUpdateDate = ThisWorkbook.Worksheets("Parameters").Range("LastUpdateDate").Value 'Named Range called LastUpdateDate on sheet "Parameters" in ThisWorkbook
'Make sure FolderName ends in a backslash
If Right(FolderName, 1) <> "\" Then FolderName = FolderName & "\"
'Get matching files for MyCriterion
FileName = Dir(FolderName & "*" & MyCriterion & "*" & ".xl??")
'Loop through all matching files
Do While FileName <> ""
If FileDateTime(FolderName & FileName) > LastUpdateDate Then 'FileDateTime requires the full file path, not just the file name
'Open the next matching workbook - work with the workbook directly, rather than working with ActiveWorkbook, ActiveSheet and Selections
Set wb = Workbooks.Open(FileName:=FolderName & FileName, ReadOnly:=True)
'Call GrabTheData on the workbook
GrabTheData wb
'Close the workbook
wb.Close SaveChanges:=False
End If
'Get the name of the next match in folder
FileName = Dir
Loop
Set wb = Nothing
End Sub
Sub GrabTheData(ByRef wb As Workbook)
Dim wsOut As Worksheet, wsIn As Worksheet
Set wsOut = ThisWorkbook.Worksheets("Aggregated Data") 'Worksheet called "Aggregated Data" in ThisWorkbook
Set wsIn = wb.Worksheets("Report Data")
' ### Manipulate the data and write to wsOut, no need to work with Selections ###
End Sub

Resources