I have this VBA code to count all values that are not zero in all excel files saved in a folder and print out the result in the worbook containing the macro. the problem I am having is that it opens the same file (the first one) over and over instead of moving to the next file.
Sub RealCount()
Dim file As String
Dim row As Integer
Dim wb As Workbook
row = 2
file = Dir("\\Daglig rapport\KPI Marknadskommunikation\FEB\*.xl??")
Do While file <> ""
Set wb = Workbooks.Open("\\Daglig rapport\KPI Marknadskommunikation\FEB\*.xl??")
Call ZeroCount
file = Dir("\\Daglig rapport\KPI Marknadskommunikation\FEB\*.xl??")
Loop
End Sub
Here's some suggestions to get it working:
Use a path variable to keep the folder location and make the code easier to read
Fix the Workbooks.Open so the parameter should be the actual file path (I'm kind of surprised Excel's Workbook.Open would actually work with wildcards characters like * or ?)
Check that ZeroCount doesn't call any Dir functions. If you do, then Excel may very well reset your ability to call Dir to correctly get the next file in your loop. If you find that this is happening and you must absolutely call Dir inside of this loop, then you could loop through all the Dir values first and store them into an array. Then make another loop that goes through that array which calls ZeroCount (or any code that needs to use Dir within it)
Here's an example of the first two points taken care of:
Sub RealCount()
Dim path as String
Dim file As String
Dim row As Integer
Dim wb As Workbook
path = "\\Daglig rapport\KPI Marknadskommunikation\FEB\"
row = 2
file = Dir(path & "*.xl??")
Do While file <> ""
Set wb = Workbooks.Open(path & file)
Call ZeroCount
row = row + 1 ' I assume you want to increment row each time as well maybe?
file = Dir()
Loop
End Sub
For some more examples of using VBA's Dir - see here: http://www.exceltrick.com/formulas_macros/vba-dir-function/
Related
I have a VBA script in an Excel workbook that gathers results from all the workbooks in a particular folder.
Private Sub Workbook_Open()
Dim path As String
Dim fso As Object
Dim folder As Object
Dim file As Object
Dim i As Integer
Dim data As Object
Set data = Worksheets("RawData")
path = data.Range("A1").Value
i = 3
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(path)
data.Rows("2:" & data.Rows.Count).ClearContents
For Each file In folder.Files
If Right(UCase(file.name), 5) = ".XLSX" And Left(file.name, 1) <> "~" Then
data.Cells(i, 2) = "='" + path + "\[" + file.name + "]Summary'!A1:J1"
i = i + 1
End If
Next file
End Sub
The idea is for each .xlsx file in a given folder, I add a reference to the results range in that file. For example, if there is a file Test1.xlsx in folder C:\Sheets, the VBA puts the following formula into some row on the sheet containing the script:
='C:\Sheets\[Test1.xlsx]Summary'!A1:J1
Excel then pulls values out of Test1 and puts them in the current workbook's RawData sheet.
This worked until today, when my formulas started ending up with # right after the = sign, like this:
=#'C:\Sheets\[Test1.xlsx]Summary'!A1:J1
This gives me a #VALUE?.
Excel helpfully gave me a message stating that it has just now started inserting # into formulas due to some syntax changes, but that it wouldn't affect calculations. I can't get this message to show up again, but that was the gist of it. Obviously it does affect calculations. If I manually remove the # from the formula, it works fine.
I have Office 365 and I guess I must have received an update recently that added this "feature" because all this used to work fine.
If I modify the VBA script to reference only a single cell, the # does not get inserted. But using a named range for the results (rather than A1:J1) still has the problem.
Anyone have any ideas for a workaround?
To avoid the # from being inserted, use the .Formula2 property of the range object.
This change has to do with the dynamic array feature of Excel O365
You could assign the formula to a variable and then remove the # from the string using the Right() function...
As the length of the string will be dynamic depending on the length of the file name, I've used the Len() function to get the full lenght of the string, then minus 2 from it to remove the = and #.
Note the = is concatenated with the Right() function when assigning the value to the cell.
Dim FormulaString as String
For Each file In folder.Files
If Right(UCase(file.name), 5) = ".XLSX" And Left(file.name, 1) <> "~" Then
FormulaString = "='" + path + "\[" + file.name + "]Summary'!A1:J1"
data.Cells(i, 2) = "=" & Right(FormulaString, Len(FormulaString) - 2)
i = i + 1
End If
Next file
Output is
='C:\Sheets\[Test1.xlsx]Summary'!A1:J1
I have some VBA code in excel 2010 that imports multiple .csv files in to one excel workbook however, sometimes there is a rogue file that contains nothing and has a file size of zero that throws up an error, I then have to manually go to the folder and delete this and run my macro again.
Therefore I'm after some help that will allow me to check the file size's of all .csv file contained in a folder and delete any that are zero before I import them. Is there a way I can do this? Or possibly another suggested method that would help?
I'm very new to VBA so please be patient if I don't fully understand straight away.
I have looked into FileLen(C:\Test\test.csv) = 0 Then Kill said file.
But this only deletes specifically the file mentioned. I would rather check all file sizes and if any are zero, kill them.
You can use the FileSystemObject to check files in a folder, and delete them if they are of the correct type and size = 0.
Be very careful running this as the deletions will be permanent (not recoverable).
Option Explicit
'Set reference to Microsoft Scripting Runtime
Sub terfuge()
Dim FSO As FileSystemObject, FI As File, FIs As Files, FO As Folder
Const strBasePath As String = "full_path_of_folder_to_search"
Dim bMsg As Integer
Set FSO = New FileSystemObject
Set FO = FSO.GetFolder(strBasePath)
Set FIs = FO.Files
For Each FI In FIs
If FI.Name Like "*.csv" Then
If FI.Size = 0 Then
bMsg = MsgBox(Prompt:="Are you sure you want to delete " & FI.Name & "?", Buttons:=vbYesNoCancel)
Select Case bMsg
Case vbYes
FI.Delete
Case vbCancel
Exit Sub
End Select
End If
End If
Next FI
End Sub
You can use the DIR command to search through all files in a folder then kill any with a file size of 0.
The code below searches through a specified folder and lists the *.xls filenames in a sheet called Main.
It should be easy to adapt this and combine with your own Kill command.
Sub Directory()
Dim strPath As String
Dim strFolderPath As String
Dim strFileName As String
Dim intRow As Integer
Dim intColumn As Integer
Dim intNumber As Integer
intRow = 1
intColumn = 1
intNumber = 0
strFolderPath = "h:\excel\*.xls" 'search through H drive excel folder
strFileName = Dir(strFolderPath) 'Get name of first file
Do
Sheets("Main").Cells(intRow, intColumn) = strFileName 'write filename
strFileName = Dir 'get next filename
intRow = intRow + 1
Loop Until strFileName = ""
End Sub
Thanks both for your speedy responses, I managed to eventually get my loop going jiggling Andy's sample.
I'd already started dabbling with his idea before Ron responded so continued with it.
I do however like the idea of the user being asked first whether or not they would like to delete the file, so I think I'll have a stab at Ron's suggestion too and maybe learn something along the way.
Thanks again.
I'm trying to create a macro that lists all the files in a given folder (and its sub folders) which match criteria for filename (in my example "job checklist") and type (in my example "*.xlsm"). since all the workbooks of this type and naming convention in my search folder are of the same type, i need to open and read values from each workbook and copy them into my host workbook. when the macro is run the run date/time should be noted in the host workbook, so that when the macro is run subsequently only new workbooks OR workbooks which have been modified since the most recent time stamp need to be opened and updated in the host workbook.
I have been trying to use some recursive code found in other posts, but threads, but i'm having a hard time to incorporate search criteria:
- file name
- file type
- modified date
[here] (VBA macro that search for file in multiple subfolders)
I have also tried to encorporate code from Pearson here to allow me to check file attributes of xls files but it doesnt seem to work (maybe due to 64 bit, though i found another version which was supposed to be compatible)
I've been trying to find a solution for several days, but am kinda stuck, any help would be appreciated.
working code i have so far which is listing all the files here of type .zip in my host workbook, i don't know how to check the modified date of a file. i assume that if i could i could add some code to open files (which meet type, name and modified (compared to a date/time value cell in the host workbook, and updates every time the macro is run) and then extract values from a known sheet/range into the host workbook.
```vba
Sub MainList()
Dim folder, xdir As Variant
Set folder = Application.FileDialog(msoFileDialogFolderPicker)
Call ListFilesInFolder("C:\Users\60066690\Desktop\Documents from BCP and loose MTC", True)
End Sub
Sub ListFilesInFolder(ByVal xFolderName As String, ByVal xIsSubfolders As Boolean)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim rowIndex As Long
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
rowIndex = Application.ActiveSheet.Range("A65536").End(xlUp).Row + 1
For Each xFile In xFolder.Files
If Not InStr(1, xFile.Name, ".zip") = 0 Then
'could need to add in here If for name, but not sure how to add If for modified date, if i could i could compare the modified date to a date cell in this workbook
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
'need to add some code in here to open the found workbook, then extract some values from known sheets/cells, store those values in variables, then close the found workbook and output the found variables to the colums beside the file name
rowIndex = rowIndex + 1
End If
Next xFile
If xIsSubfolders Then
For Each xSubFolder In xFolder.SubFolders
ListFilesInFolder xSubFolder.Path, True
Next xSubFolder
End If
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
End Sub
```
I want to create a macro that can check and open file based on filename.
ex:
15.xlsm As opened workbook
12.xlsm As a target
16.xlsm As the future workbook
So while I click a button in 15.xlsm that will open the previous file (12.xlsm). But in future, when the 16.xlsm is created, the 16.xlsm must open the previous workbook (15.xlsm).
I was trying with this code
Sub Macro1()
Dim a, x As Integer
Dim path, filename As String
Dim varday, varyest As Long
varday = Day(Range("A1"))
For x = 1 To 30
varyest = varday - x
filename = "" & varyest & ".xlsm"
path = "F:\Kemal\" & filename & ""
If Dir(path) = "" Then
Else
Workbooks.Open filename:=path
End If
Next x
End Sub
but that code has open all workbook like 12.xlsm, 10.xlsm, 9.xlsm, and create unlimited messagebox. Yeah I know the algorithm but, how to put it into code is the big problem. anyone help me, pls.
So, How to check previous file is exist or not with date that placed on every workbook name?
to know if file exists :
CreateObject("Scripting.FileSystemObject").FileExists(p)
If you want to check MANY files, you may want to use the content of the whole folder and lookup the array.
if target workbooks has a Workbook_Open that's not to be launched:
Application.EnableEvents = False
workbooks.open(file)
Application.EnableEvents = true
Question is a bit fuzzy to me, I hope this answers
I need to export data in a sheet to a text file without changing the file name (i.e. not doing "save as". Also it would be great if the file name could look at the previous like file name in the folder and increase by 1 digit (i.e. :file_1.txt, file_2.txt, etc.)...
Thanks!!
If you want to avoid the current name of your excel file being changed, just save the current worksheet, not the whole workbook (the VBA equivalent of the SaveAs function is ActiveWorkbook.SaveAS, to save just the current sheet use ActiveSheet.SaveAS).
You can use the following macro:
Sub Macro1()
Application.DisplayAlerts = False
ActiveSheet.SaveAs Filename:="NewFile.txt", FileFormat:=xlTextWindows
Application.DisplayAlerts = True
End Sub
Toggling the DisplayAlerts property avoids a message box that is displayed if the given file already exists.
If want to save more than one sheet, you need to iterate through the Sheets collection of the ActiveWorkbook object and save each sheet to a separate file.
You can get a new file name as illustrated below, it includes a date. If you would like to add some details on what you want to export, you may get a fuller answer.
Function NewFileName(ExportPath)
Dim fs As Object '' or As FileSytemObject if a reference to
'' Windows Script Host is added, in which case
'' the late binding can be removed.
Dim a As Boolean
Dim i As Integer
Dim NewFileTemp As string
Set fs = CreateObject("Scripting.FileSystemObject")
NewFileTemp = "CSV" & Format(Date(),"yyyymmdd") & ".csv"
a = fs.FileExists(ExportPath & NewFileTemp)
i = 1
Do While a
NewFileTemp = "CSV" & Format(Date(),"yyyymmdd") & "_" & i & ".csv"
a = fs.FileExists(ExportPath & NewFileTemp)
i = i + 1
If i > 9 Then
'' Nine seems enough times per day to be
'' exporting a table
NewFileTemp = ""
MsgBox "Too many attempts"
Exit Do
End If
Loop
NewFileName = NewFileTemp
End Function