Loop cells in VBA. - vba

I am trying to make my code better, as every beginner I have problem to make it more "systematic", I would like your advice on how to do it.
I open few workbook, so now my macro looks like this.
Sub OpenWorkbooks()
workbooks.Open Filename :="C/.../file1.xlsx"
workbooks.Open Filename :="C/.../file2.xlsx"
workbooks.Open Filename :="C/.../file3.xlsx"
.
.
End sub
Its quite ugly, I would like to have each path in a cell. Let say from A1 to A3 and to loop this cell to open the workbooks. Any idea how I could do this?
In an other part of my code, nicely found on the web, I have the same problem. I would like to be able to enter my paths somewhere in my spreadsheet and then to loop it from there instead of entering manually one by one...
This is the second part of the code, quite clueless how I should do this...
Sub GetNumber()
Dim wWbPath As String, WbName As String
Dim WsName As String, CellRef As String
Dim Ret As String
Workbooks("file1").Close SaveChanges:=True
wbPath = "C:/etc...."
WbName = "file1.xlsx"
WsName = "Sheet1"
CellRef = "AD30"
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
Worksheets("Sheet1").Range("A1") = ExecuteExcel4Macro(arg)
'Then I need to do all again for the second workbook etc....
End sub
Any idea is welcome,
Thank you!

To answer the first part of your question:
Sub OpenWorkbooks()
For i = 1 to 3 ' Loop 3 times
Workbooks.Open Filename:=Sheet1.cells(i,1).value
'Cells refers to Row and column, so i will iterate three times while keeping the column the same.
Next i
End sub
If you don't know how many loops you will want to make, you could use the following to check the Last Row with data and loop until you reach it:
Sub OpenWorkbooks()
LastRow = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 to LastRow ' Loop as many times until the last row with data
Workbooks.Open Filename:=Sheet1.cells(i,1).value
'Cells refers to Row and column, so i will iterate three times while keeping the column the same.
Next i
End sub
For the second part of your code you could do something like:
Sub GetNumber()
Dim wWbPath As String, WbName As String
Dim WsName As String, CellRef As String
Dim Ret As String
For i = 1 to 5 'Change this to however many files you will be using
FileName = Sheet1.cells(i,1).value
Workbooks(FileName).Close SaveChanges:=True
wbPath = "C:/etc...."
WbName = FileName & ".xlsx"
WsName = "Sheet1"
CellRef = "AD30"
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
Worksheets("Sheet1").Range("A" & i) = ExecuteExcel4Macro(arg)
'Then I need to do all again for the second workbook etc....
Next i
End sub

I had to figure out how do something similar recently. Try this ...
Dim i As Long
Dim SelectedFiles As Variant
SelectedFiles = Application.GetOpenFilename("Excel Files (*.xlsx), *.xlsx", _
Title:="Select files", MultiSelect:=True)
If IsArray(SelectedFiles) Then
For i = LBound(SelectedFiles) To UBound(SelectedFiles)
Set wbkToOpen = Workbooks.Open(Filename:=SelectedFiles(i), corruptload:=xlRepairFile)
Debug.Print wbkToOpen.Name
Debug.Print SelectedFiles(i)
wbkToOpen.Close savechanges:=False
Next
End If

Related

VBA Export Sheets to Separate CSV Starting at Sheet 4 and beyond

as the title suggests, I'm trying to export sheets (starting from the fourth sheet and beyond, this is a fixed value) to separate CSV files. Ideally it would be right into a folder on the desktop containing each files. Below is the code I've been working with / trying to tweak-
Sub ExportSheetsToCSV()
Dim xWs As Worksheet
Dim xcsvFile As String
For Each xWs In Application.ActiveWorkbook.Worksheets
xWs.Copy
xcsvFile = CurDir & "\" & xWs.Name & ".csv"
Application.ActiveWorkbook.SaveAs Filename: = xcsvFile, _
FileFormat: = xlCSV, CreateBackup: = False
Application.ActiveWorkbook.Saved = True
Application.ActiveWorkbook.Close
Next
End Sub
Use the worksheets collection index.
Sub ExportSheetsToCSV()
Dim xWs As Worksheet
Dim xcsvFile As String, w as long
For w=4 to ActiveWorkbook.Worksheets.count
with ActiveWorkbook.Worksheets(w)
xcsvFile = CurDir & "\" & .Name & ".csv"
.Copy
with ActiveWorkbook
.SaveAs Filename:=xcsvFile, FileFormat:=xlCSV
.Close savechanges:=false
end with
end with
Next w
end sub
Is CurDir appropriate here? ActiveWorkbook.Path may be another option.

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 Sheet Name Error

I'm using a VBA code to cycle through excel files in a directory and pull information from one worksheet and paste into a newly created worksheet. I'm also naming my new worksheets (in my destination file) by the name in one of the cells in the source file.
My code works for the first loop but fails/stops in the second loop (VBA points to an error in the Dest.Sheets.Add(After:=Dest.Sheets(Dest.Sheets.Count)).Name = Sheetname line. I need to loop through 75 of these files and I'm unsure of what's going on because it works correctly for the first file.
Thanks so much for the help!
Sub AddSummaryTables()
Dim Spath, Filename, Sheetname As String
Dim Source, Dest As Workbook
Dim WS As Worksheet
Set Dest = ThisWorkbook
Spath = InputBox("Enter File Source Path") & "\"
Filename = Dir(Spath & "*.xls*")
Do While Filename <> ""
Set Source = Workbooks.Open(Spath & Filename)
Sheetname = Source.Sheets("Summary").Range("B2").Text
MsgBox Sheetname
Dest.Sheets.Add(After:=Dest.Sheets(Dest.Sheets.Count)).Name = Sheetname
Source.Sheets("Summary").Range("A1:R150").Copy
Dest.Worksheets(Sheetname).Range("A1").PasteSpecial xlPasteValues
Dest.Worksheets(Sheetname).Range("A1").PasteSpecial xlPasteFormats
Dest.Worksheets(Sheetname).Range("A1:R150").WrapText = False
Dest.Worksheets(Sheetname).Rows.AutoFit
Dest.Worksheets(Sheetname).Columns.AutoFit
Source.Close SaveChanges:=False
Dest.Save
Filename = Dir()
Loop
End Sub
following Comintern's and Wyatt's suggestion you could try like follows
Option Explicit
Sub AddSummaryTables()
Dim sPath As String, fileName As String
Dim sourceWb As Workbook, destWb As Workbook
Dim sourceWs As Worksheet, destWs As Worksheet
Set destWb = ThisWorkbook
sPath = InputBox("Enter File Source Path") & "\"
fileName = Dir(sPath & "*.xls*")
Do While fileName <> ""
Set sourceWb = Workbooks.Open(sPath & fileName)
Set sourceWs = GetWorksheet(sourceWb, "Summary")
If Not sourceWs Is Nothing Then
Set destWs = SetWorksheet(destWb, sourceWs.Range("B2").Text)
sourceWs.Range("A1:R150").Copy
With destWs
.Range("A1").PasteSpecial xlPasteValues
.Range("A1").PasteSpecial xlPasteFormats
.UsedRange.WrapText = False
.Rows.AutoFit
.Columns.AutoFit
End With
sourceWb.Close SaveChanges:=False
destWb.Save
End If
fileName = Dir()
Loop
End Sub
Function GetWorksheet(wb As Workbook, sheetName As String) As Worksheet
On Error Resume Next
Set GetWorksheet = wb.Worksheets(sheetName)
On Error GoTo 0
End Function
Function SetWorksheet(wb As Workbook, sheetName As String) As Worksheet
Dim i As Integer
Do While Not GetWorksheet(wb, sheetName & IIf(i = 0, "", "-" & i)) Is Nothing
i = i + 1
Loop
With wb
.Worksheets.Add(After:=.Worksheets(.Worksheets.Count)).Name = sheetName & IIf(i = 0, "", "-" & Format(i, "000"))
Set SetWorksheet = .ActiveSheet
End With
End Function
where you make sure that
any opened workbook has a "Summary" worksheet
you name worksheets in your destination workbook such as not to have duplicates: if you happen to deal with say three worksheets named "Sheet5" then your destination workbook will have added worksheets "Sheet5", "Sheet5-001" and "Sheet5-002".
You're issue may be that when you are adding the sheet from the second workbook, it has the same name as the sheet from the first workbook. You could check if the sheet exists and add a number to it. The post below might help.
Test or check if sheet exists

How to Change the File Names of Selected Rows using Excel VBA

I'm trying to write a VBA macro that changes file names from the text in Column B to the text of Column A. For example, if I had:
Column A: Stack Overflow
Column B: Question
It would change Question.txt to Stack Overflow.txt. As of now I've slightly modified the code from the answer here to read:
Sub rename()
Dim Source As Range
Dim OldFile As String
Dim NewFile As String
Set Source = Cells(1, 1).CurrentRegion
For Row = 2 To Source.Rows.Count
OldFile = ActiveSheet.Range("D1").Value & ("\") & ActiveSheet.Cells(Row, 1) & (".pdf")
NewFile = ActiveSheet.Range("D1").Value & ("\") & ActiveSheet.Cells(Row, 2) & (".pdf")
' rename files
Name OldFile As NewFile
Next
End Sub
This works great, but I'm trying to get it to only run on selected rows; my ideal end result is that I can select the 15 non-consecutive rows that I want to change, run the macro, and have it only apply to those 15. I tried the below code but the ActiveSheet.Cells(Row, 1) function is returning a Run-Time Error 1004, Application-defined or object-definied error; is there a good way around this?
Sub renameMain()
Dim OldFile As String
Dim NewFile As String
Dim rng As Range
Set rng = Selection
For Each Row In rng
OldFile = ActiveSheet.Range("O1").Value & "\" & ActiveSheet.Range(Row, 2) & ".pdf"
NewFile = ActiveSheet.Range("O1").Value & "\" & ActiveSheet.Range(Row, 1) & ".pdf"
' rename files
Name OldFile As NewFile
Next Row
End Sub
Any advice would be much appreciated!
Non contiguous rows in the Selection object can be accessed using its .Areas collection:
Option Explicit
Sub renameMain()
Dim oldFile As String, newFile As String
Dim selArea As Range, selRow As Range, staticVal As String
With ActiveSheet
staticVal = .Range("O1").Value2 & "\"
For Each selArea In Selection.Areas
For Each selRow In selArea.Rows
oldFile = staticVal & .Cells(selRow.Row, 2).Value2
newFile = staticVal & .Cells(selRow.Row, 1).Value2
Name oldFile & ".pdf" As newFile & ".pdf" 'rename files
Next
Next
End With
End Sub
You seem to want to use Row as an int variable. It isn't. Maybe try this:
Sub renameMain()
Dim OldFile As String
Dim NewFile As String
Dim rng As Range
Dim i as long
Set rng = Selection
For i = 1 To rng.Rows.Count
OldFile = ActiveSheet.Range("O1").Value & "\" & rng.Cells(i, 2) & ".pdf"
NewFile = ActiveSheet.Range("O1").Value & "\" & rng.Cells(i, 1) & ".pdf"
' rename files
Name OldFile As NewFile
Next i
End Sub

Visual Basic, Check if a sheet exists in another workbook

I'm really new to Visual Basic and I don't know any python either, I'm trying to write code that is able to check if a worksheet exists in a workbook...
Sub sheetexist()
If Len(Dir(("C:\My Data\Performance Spreadsheets\[ABCD - Performance.xls]Jun 14"))) Then
MsgBox "Sheet exist"
Else
MsgBox "Sheet does not exist"
End If
End Sub
ABCD does have the sheet for Jun 14 however the code only returns "Sheet does not exist", is there another way to check for worksheets in other workbooks?
I think you're mis-using the Dir function.
The easiest way to check if a sheet exists is with error-handling.
Function SheetExists(wbPath as String, shName as String)
Dim wb as Workbook
Dim val
'Assumes the workbook is NOT open
Set wb = Workbooks.Open(wbPath)
On Error Resume Next
val = wb.Worksheets(shName).Range("A1").Value
SheetExists = (Err = 0)
'Close the workbook
wb.Close
End Function
Call the function like this from a worksheet cell:
=SheetExists("C:\My Data\Performance Spreadsheets\ABCD - Performance.xls", "Jun 14")
Or from VBA like:
Debug.Print SheetExists("C:\My Data\Performance Spreadsheets\ABCD - Performance.xls", "Jun 14")
Without opening the workbook, you could use the code here.
This will raise an error if any part of the formula can't evaluate (e.g., if you pass the name of a non-existent sheet, a bad file path, etc., Error 2023:
Private Function GetInfoFromClosedFile(ByVal wbPath As String, _
wbName As String, wsName As String, cellRef As String) As Variant
Dim arg As String
GetInfoFromClosedFile = ""
If Right(wbPath, 1) <> "\" Then wbPath = wbPath & "\"
If Dir(wbPath & "\" & wbName) = "" Then Exit Function
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
On Error Resume Next
GetInfoFromClosedFile = ExecuteExcel4Macro(arg)
End Function
Call it:
Sub Test()
Dim path As String
Dim filename As String
Dim sheetName As String
Dim cellAddress As String
path = "c:\users\you\desktop"
filename = "file.xlsx"
sheetName = "Jun 14"
cellAddress = "A1"
Dim v As Variant 'MUST BE VARIANT SO IT CAN CONTAIN AN ERROR VALUE
v = GetInfoFromClosedFile(path, filename, sheetName, cellAddress)
If IsError(v) Then MsgBox "Sheet or filename doesn't exist!"
End Sub