Injecting Code to format all columns as text to retain leading zeros from CSVs - vba

So here is 1 part of a 3 part macro that lets you browse to a folder and consolidate/transpose/retain header of a bunch of .csv files. The problem we have is where to inject some code so that routing and account numbers are formatted as text and retain their leading zeros. If the easiest solution is to just format the entire sheet as text, that would work for us...whatever it takes without having to go into specifics since this info wont always be in the same column.
Thanks in advance!
Option Explicit
'Set a public constant variable
Public Const DNL As String = vbNewLine & vbNewLine
Sub ImportData()
'Declare all variables
Dim wb As Workbook, ws As Worksheet
Dim wbX As Workbook, wsX As Worksheet
Dim i As Long, iRow As Long, iFileNum As Long, sMsg As String
Dim vFolder As Variant, sSubFolder As String, sFileName As String
Dim bOpen As Boolean
'Turn off some application-level events to improve code efficiency
Call TOGGLEEVENTS(False)
'Have the user choose the folder
vFolder = BrowseForFolder()
'Exit if nothing was chosen, variable will be False
If vFolder = False Then Exit Sub
'Check if this is what the user wants to do, confirm with a message box, exit if no
sMsg = "Are you sure you want to import data from this folder:"
sMsg = sMsg & DNL & vFolder
If MsgBox(sMsg, vbYesNo + vbDefaultButton2, "ARE YOU SURE?") <> vbYes Then Exit Sub
'Set sub-folder as variable for save name at end of routine
sSubFolder = Right(vFolder, Len(vFolder) - InStrRev(vFolder, Application.PathSeparator))
'Set destination file with one worksheet
Set wb = Workbooks.Add(xlWBATWorksheet)
Set ws = wb.Sheets(1)
'This will be the row to start data on, to incriment in loop
iRow = 2
'Loop through files in folder
sFileName = Dir$(vFolder & "\")
Do Until sFileName = ""
'Check that the file pattern matches what you want, i.e. 12.16.00.xls
If sFileName Like "*.csv" Then '### set file extension here
'Check to see if the file is open
'If file is open, set as variable, if not, open and set as variable
If ISWBOPEN(sFileName) = True Then
Set wbX = Workbooks(sFileName)
bOpen = True
Else
Set wbX = Workbooks.Open(vFolder & "\" & sFileName)
bOpen = False
End If
'Set first sheet in target workbok as worksheet variable, from which to mine data
Set wsX = wbX.Sheets(1)
'Get last row from column A (range for copy/pasting)
i = wsX.Cells(wsX.Rows.Count, 1).End(xlUp).Row
'Check if a file has been added, if not add headers (frequency)
If iFileNum = 0 Then
ws.Range("B1", ws.Cells(1, i + 1)).Value = Application.Transpose(wsX.Range("A1:A" & i))
End If
'Add data
ws.Range("B" & iRow, ws.Cells(iRow, i + 1)).Value = Application.Transpose(wsX.Range("B1:B" & i))
'Add file name to column A
ws.Range("A" & iRow).Value = "'" & Left$(sFileName, Len(sFileName) - 4)
'Incriment variable values
iRow = iRow + 1
iFileNum = iFileNum + 1
'If file was closed to start with, clean up and close it
If bOpen = False Then wbX.Close SaveChanges:=False
End If
'Get next file name
sFileName = Dir$()
Loop
'Check if file name to save exists
If Dir$(vFolder & "\" & sSubFolder & ".xls", vbNormal) = "" Then
wb.SaveAs vFolder & "\" & sSubFolder & ".xls"
MsgBox "Complete!", vbOKOnly
Else
MsgBox "File already exists! File is NOT saved!", vbInformation, "COMPLETE!"
End If
'Reset events back to application defaults
Call TOGGLEEVENTS(True)
End Sub

Related

combine multiple text files in a single excel sheet

I have 27 txt files with the same format and columns, and I want to append all of these in a single excel sheet. I have checked some previous threads here, but I could only find the code below which helped me to import txt fiels into separate sheets. However, I also want to append these separate sheets into a sheet that I want to append all my data.
Sub Test()
'UpdatebyExtendoffice6/7/2016
Dim xWb As Workbook
Dim xToBook As Workbook
Dim xStrPath As String
Dim xFileDialog As FileDialog
Dim xFile As String
Dim xFiles As New Collection
Dim I As Long
Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
xFileDialog.AllowMultiSelect = False
xFileDialog.Title = "Select a folder [Vendor_data_25DEC]"
If xFileDialog.Show = -1 Then
xStrPath = xFileDialog.SelectedItems(1)
End If
If xStrPath = "" Then Exit Sub
If Right(xStrPath, 1) <> "\" Then xStrPath = xStrPath & "\"
xFile = Dir(xStrPath)
'xFile = Dir(xStrPath & "*.txt") 'this is the original version that you can amend according to file extension
If xFile = "" Then
MsgBox "No files found", vbInformation, "Vendor_data_25DEC"
Exit Sub
End If
Do While xFile <> ""
xFiles.Add xFile, xFile
xFile = Dir()
Loop
Set xToBook = ThisWorkbook
If xFiles.Count > 0 Then
For I = 1 To xFiles.Count
Set xWb = Workbooks.Open(xStrPath & xFiles.Item(I))
xWb.Worksheets(1).Copy after:=xToBook.Sheets(xToBook.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = xWb.Name
On Error GoTo 0
xWb.Close False
Next
End If
End Sub
I am not sure how to do this with VBA in order to combine the data in separate sheets into a single sheet quickly. I know the consolidate feature of excel but it also includes lots of manual steps, so I seek for a faster and automated solution. Any help is much appreciated.
Thanks a lot in advance.
Sub Combiner()
Dim strTextFilePath$, strFolder$
Dim wksTarget As Worksheet
Dim wksSource As Worksheet
Dim x As Long
Set wksTarget = Sheets.Add()
strFolder = "c:\Temp\test\"
strTextFilePath = Dir(strFolder)
While Len(strTextFilePath) > 0
'// "x" variable is just a counter.
'// It's purpose is to track whether the iteration is first or not.
'// If iteration is first (x=1), then we include header (zero offset down),
'// otherwise - we make an offset (1 row offset down).
x = x + 1
Set wksSource = Workbooks.Open(strFolder & strTextFilePath).Sheets(1)
With wksTarget
wksSource.Range("A1").CurrentRegion.Offset(IIf(x = 1, 0, 1)).Copy _
.Cells(.Rows.Count, 1).End(xlUp).Offset(1)
End With
wksSource.Parent.Close False
strTextFilePath = Dir()
Wend
MsgBox "Well done!", vbInformation
End Sub

VBA Change code from MSG Box to Summary Report

Good afternoon,
I have tried searching different forums to no avail.
I have the below VBA code that will loop through all files in a folder and generate in a msge box the total number of rows of every file looped in that folder.
What I need your help on if possible is generate a summary report.
Ideally
The summary report will show File name and show how many rows with data in column H.
Sub LoopThroughFiles()
Dim folderPath As String
folderPath = ThisWorkbook.Path & "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename, ReadOnly:=True)
For Each sh In wb.Sheets
If Application.CountA(sh.Range("H:H")) > 0 Then
myCount = myCount + sh.Range("H" & Rows.Count).End(xlUp).Row
End If
Next
wb.Close False
Filename = Dir
Set wb = Nothing
Loop
MsgBox myCount
End Sub
You could try opening a "home" workbook where all values are stored. Basically, what you'll need to do is open a new workbook, and during your loop through each of the files, you'll paste the file path and the row count in the new workbook. Hopefully this will help, or at least give you an idea of how to do what you're trying to do. `
Sub LoopThroughFiles()
Dim folderPath As String
Dim summarySheet as Workbook
set summarySheet = workbook.add
folderPath = ThisWorkbook.Path & "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename, ReadOnly:=True)
For Each sh In wb.Sheets
If Application.CountA(sh.Range("H:H")) > 0 Then
myCount = myCount + sh.Range("H" & Rows.Count).End(xlUp).Row
End If
Next
wb.Close False
summarySheet.activate
Range("A:A").insert Shift:=xlDown
Cells(1,1) = Filename
Cells(1,2) = myCount
Filename = Dir
Set wb = Nothing
Loop
MsgBox myCount
End Sub`

Excel VBA - save as with .xlsx extension

Here's the code I have for renaming a file. It does a SaveAs and then deletes the original. This needs to be ran on different types of workbooks: some have a .xls extension, others have a .xlsx extension. If it has a .xls extension, I need to force it to have a .xlsx extension somehow.
How can I do this other than by manually typing an "x" at the end of the blank in the InputBox when it pops up?
Or maybe there's a different solution to this problem? My goal is to force the InputBox to show the current filename with a .xlsx extension regardless of what is currently is.
Sub RenameFile()
Dim myValue As Variant
Dim thisWb As Workbook
Set thisWb = ActiveWorkbook
MyOldName2 = ActiveWorkbook.Name
MyOldName = ActiveWorkbook.FullName
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
ActiveWorkbook.Name)
If MyNewName = vbNullString Then Exit Sub
If MyOldName2 = MyNewName Then Exit Sub
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=thisWb.Path & "\" & MyNewName, _
FileFormat:=51
Kill MyOldName
End Sub
If the new extension is always going to be .xlsx, why not leave the extension out of the input box entirely:
Dim fso As New Scripting.FileSystemObject
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
fso.GetBaseName(ActiveWorkbook.Name)) & ".xlsx"
Note that this requires a refernece to Microsoft Scripting Runtime.
Do you want to present the extension at the point of the MsgBox or after? The following code will force the extension to be changed to whatever type you specify. Just add code for other conversions you want to handle. If you want to present the new extension in the Msgbox, copy the code I added and place before the MsgBox. If you want to 'guarantee' new extension, you need to keep the code after the Msgbox in case user overrules your suggestion.
Sub RenameFile()
Dim myValue As Variant
Dim thisWb As Workbook
Dim iOld As Integer
Dim iNew As Integer
Dim iType As Integer
Set thisWb = ActiveWorkbook
Dim MyOldName2, MyOldName, MyNewName As String
MyOldName2 = ActiveWorkbook.Name
MyOldName = ActiveWorkbook.FullName
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
ActiveWorkbook.Name)
If MyNewName = vbNullString Then Exit Sub
If MyOldName2 = MyNewName Then Exit Sub
iOld = InStrRev(MyOldName, ".")
iNew = InStrRev(MyNewName, ".")
If LCase(Mid(MyOldName, iOld)) = ".xls" Then
MyNewName = Left(MyNewName, iNew - 1) & ".xlsx"
iType = 51
ElseIf LCase(Mid(MyOldName, iOld + 1)) = ".YYYY" Then ' Add lines as needed for other types
MyNewName = Left(MyNewName, iNew - 1) & ".ZZZZ" ' Must change type to match desired output type
iType = 9999
Else
MsgBox "Add code to handle extension name of '" & LCase(Mid(MyOldName, iOld)) & "'", vbOKOnly, "Add Code"
Exit Sub
End If
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=thisWb.Path & "\" & MyNewName, FileFormat:=iType
Kill MyOldName
End Sub

copying data from a folder of workbooks into a single worksheet iteration through loop in VBA

I am trying to copy data from a couple of workbooks present in a folder into a single workbook. I am looping through the folder to fetch the data from the various workbooks but I need to paste the data spanning from A5:D5 in loop.
i.e A5:D5 in the destination sheet is one workbook's data in the folder, I need the other set of data to be copied into A6:D6 and so on for the number of workbooks in the folder. Please help me loop through this.
Private Sub CommandButton1_Click()
Dim wbk As Workbook
Dim Filename As String
Dim Path As String
Path = "D:\Macro_Demo\estimation_sheets\"
Filename = Dir(Path & "*.xls")
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
'--------------------------------------------
'OPEN EXCEL FILES
Do While Len(Filename) > 0 'IF NEXT FILE EXISTS THEN
Set wbk = Workbooks.Open(Path & Filename)
target.Sheets("Metrics_Data").Range("A5").Value = wbk.Sheets("summary").Range("I5").Value
target.Sheets("Metrics_Data").Range("B5").Value = wbk.Sheets("summary").Range("I6").Value + wbk.Sheets("summary").Range("I7")
target.Sheets("Metrics_Data").Range("C5").Value = wbk.Sheets("summary").Range("I8").Value
target.Sheets("Metrics_Data").Range("D5").Value = wbk.Sheets("summary").Range("I9").Value
MsgBox Filename & " has opened"
wbk.Close True
Filename = Dir
Loop
MsgBox "Task complete!"
End Sub
Try this:
Private Sub CommandButton1_Click()
Dim wbk As Workbook, target As Workbook, excelFile As String, path As String, rw As Integer
path = "D:\Macro_Demo\estimation_sheets\"
excelFile = Dir(path & "*.xls")
rw = 5
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
Do While excelFile <> ""
Set wbk = Workbooks.Open(path & excelFile)
With target.Sheets("Metrics_Data")
.Range("A" & rw) = wbk.Sheets("summary").Range("I5")
.Range("B" & rw) = wbk.Sheets("summary").Range("I6") + wbk.Sheets("summary").Range("I7")
.Range("C" & rw) = wbk.Sheets("summary").Range("I8")
.Range("D" & rw) = wbk.Sheets("summary").Range("I9")
End With
wbk.Close True
rw = rw + 1
excelFile = Dir
Loop
MsgBox "Task complete!"
End Sub
You need to find the next available row on your destination sheet, store that in a variable, and write the data relative to that cell. Like this
Private Sub CommandButton1_Click()
Dim shSource As Worksheet, shDest As Worksheet
Dim sFile As String
Dim rNextRow As Range
Const sPATH As String = "D:\Macro_Demo\estimation_sheets\"
'Open the destination workbook
Set shDest = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest.xls").Worksheets("Metrics_Data")
sFile = Dir(sPATH & "*.xls")
Do While Len(sFile) > 0
Set shSource = Workbooks.Open(sPATH & sFile).Worksheets("summary")
'start at row 1000 and go up until you find something
'then go down one row
Set rNextRow = shDest.Cells(1000, 1).End(xlUp).Offset(1, 0)
'Write the values relative to rNextRow
With rNextRow
.Value = shSource.Range("I5").Value
.Offset(0, 1).Value = shSource.Range("I6").Value
.Offset(0, 2).Value = shSource.Range("I8").Value
.Offset(0, 3).Value = shSource.Range("I9").Value
End With
'Close the source
shSource.Parent.Close False
sFile = Dir
Loop
MsgBox "Done"
End Sub

DIR loop with specific sheet names

I have 5 files in a folder. I need to split a sheet called Marrs Upload into a separate worksheet.
I've managed to get it to work for the first file but after that it comes up with the "Run Time error: 9 Subscript out of range" message.
Here is my current code:
Sub Hello()
StrFile = Application.ActiveWorkbook.Path + "\" 'Get path name
GetFullFile = ActiveWorkbook.Name 'File name
sFilename = Left(GetFullFile, (InStr(GetFullFile, ".") - 1)) 'Fine the . and
i = 1 'Part of the name counter
ExportFile = StrFile + "Import to Marrs\"
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ") ' Saves the filename Marrs Upload (Date) followed by counter
Application.DisplayAlerts = False
strFilename = Dir(StrFile)
If Len(strFilename) = 0 Then Exit Sub ' exit if no files in folder
Do Until strFilename = ""
Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
ActiveWorkbook.Close (False)
ActiveWorkbook.SaveAs (ExportFile & SaveAsFileName & i)
'ActiveWorkbook.Close (False)
'ActiveWorkbook.Close (False)
i = i + 1
strFilename = Dir()
Loop
End Sub
I've tried most things and cannot get any further.
Kind Regards,
Ashley
I've added to original code to only work if a certain sheet name exists.
Sub Hello()
StrFile = Application.ActiveWorkbook.Path + "\" 'Get path name
GetFullFile = ActiveWorkbook.Name 'File name
sFileName = Left(GetFullFile, (InStr(GetFullFile, ".") - 1)) 'Find the . and returns only file name minus extension
i = 1 'Counter
ExportFile = StrFile + "Import to Marrs\" 'Saves new worksheet in a specific folder
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ") ' Saves the filename Marrs Upload (Date) followed by counter
Application.DisplayAlerts = False 'Don't display alerts "Overwrite, ect"
StrFileName = Dir(StrFile) 'No extension as can be a combination of .xlsm and .xls
Do While Len(StrFileName) > 0 'Loop when files are in DIR
If CheckSheet("Marrs Upload") Then 'if workseet contains a tab called "Marrs Upload" then continue.
Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
ActiveWorkbook.SaveAs (ExportFile & SaveAsFileName & i) 'Save worksheet as Marrs Upload (Date) (Counter)
ActiveWorkbook.Close (False) 'Don't need to save original file (Audit Trail)
i = i + 1 'Increase counter by 1
End If
StrFileName = Dir() 'used when worksheet doesn't contain sheet called "Marrs Upload"
Loop
End Sub
Function CheckSheet(ByVal sSheetName As String) As Boolean
Dim oSheet As Worksheet
Dim bReturn As Boolean
For Each oSheet In ActiveWorkbook.Sheets
If oSheet.Name = sSheetName Then
bReturn = True
Exit For
End If
Next oSheet
CheckSheet = bReturn
End Function
Kind Regards,
Ashley
EDIT: Tested, and works for me.
Sub Hello()
Dim SourceFolder As String, DestFolder As String
Dim f As String, SaveAsFileName As String, sFileName As String
Dim i As Long, wb As Workbook
'*** if ActiveWorkbook has the macro, safer to use ThisWorkbook
SourceFolder = Application.ActiveWorkbook.Path + "\"
DestFolder = SourceFolder & "Import to Marrs\"
'*** what are you doing with this?
sFileName = Left(ActiveWorkbook.Name, _
(InStr(ActiveWorkbook.Name, ".") - 1))
' Saves the filename Marrs Upload (Date) followed by counter
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ")
Application.DisplayAlerts = False
i = 1 'Part of the name counter
f = Dir(SourceFolder & "*.xls*") '*** use wildcard for XL files only
Do While Len(f) > 0
Debug.Print f
Set wb = Workbooks.Open(SourceFolder & f)
If CheckSheet(wb, "Marrs Upload") Then
wb.Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
'*** the wb with the moved sheet is now active: save it
With ActiveWorkbook
.SaveAs (DestFolder & SaveAsFileName & i)
.Close True
End With
i = i + 1
End If
wb.Close False '***close the one we just opened. Not saving?
f = Dir() '*** next file
Loop
End Sub
Function CheckSheet(wb as WorkBook, ByVal sSheetName As String) As Boolean
Dim oSheet As Worksheet
Dim bReturn As Boolean
For Each oSheet In wb.WorkSheets
If oSheet.Name = sSheetName Then
bReturn = True
Exit For
End If
Next oSheet
CheckSheet = bReturn
End Function