I am trying to run a command to open all workbooks from a query. Once open I am looking to edit the same cells in each tab for each workbook. The code below, works to open, and edit each workbook in the query when trying to update to run through each active sheet in the workbooks it will only update the first sheet. The second set is what I have tried to have it loop through each sheet.
Open and update the first active sheet in each workbook
Sub UpdateMetrics()
Dim wb As Workbook
For Each Cell In Selection
Set wb = Workbooks.Open(Cell.Value)
Range("A1").Value = "Test"
wb.Save
wb.Close
Next
End Sub
Loop through each sheet:
Sub UpdateMetricsTest()
Dim wb As Workbook
Dim ws As Worksheet
For Each Cell In Selection
Set wb = Workbooks.Open(Cell.Value)
For Each ws In Worksheets
Range("A1").Value = "Test"
Next ws
Next
End Sub
Loop Through Each Worksheet of Each Workbook
This will write a value (Test) into the same cell (A1) of each worksheet of each file (workbook) that is opened. The list of the file paths (e.g. C:\Test\Test1.xlsx) is in a column (A; more accurately A2:ALastRow) of a worksheet (Sheet1) of the workbook containing this code (ThisWorkbook).
Option Explicit
Sub UpdateMetrics()
' Source (read from)
Const sName As String = "Sheet1"
Const sCol As String = "A"
Const sfRow As Long = 2
' Destination (write to)
Const dCellAddress As String = "A1"
Const dCellValue As String = "Test"
' Reference the source (one-column) range containing the file paths.
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = swb.Worksheets(sName)
Dim srg As Range: Set srg = sws.Range(sws.Cells(sfRow, sCol), _
sws.Cells(sws.Rows.Count, sCol).End(xlUp)) ' ('A2:ALastRow')
Application.ScreenUpdating = False
Dim sCell As Range
Dim dwb As Workbook
Dim dws As Worksheet
Dim dFilePath As String
' Loop through the cells of the source range.
For Each sCell In srg.Cells
dFilePath = CStr(sCell.Value) ' Tolerate error values by using 'CStr'.
If Len(dFilePath) > 0 Then ' cell is not blank
If Len(Dir(dFilePath)) > 0 Then ' file exists
On Error Resume Next ' Attempt to open the file:
Set dwb = Workbooks.Open(dFilePath)
On Error GoTo 0
If Not dwb Is Nothing Then ' file was opened
' Loop through the worksheets in the current workbook...
For Each dws In dwb.Worksheets
' ... and write the value to each worksheet's cell.
dws.Range(dCellAddress).Value = dCellValue
Next dws
dwb.Close SaveChanges:=True
Set dwb = Nothing
'Else ' file was not opened; do nothing
End If
'Else ' file does not exist; do nothing
End If
'Else ' cell is blank; do nothing
End If
Next sCell
Application.ScreenUpdating = True
' Inform.
MsgBox "Metrics updated.", vbInformation
End Sub
Related
I have a template workbook that I need 100s of copies of ("Template"). I have the list of titles of each workbook in Sheet 2 ("Data") of this template workbook.
I've dug around on this site and found this code that does almost exactly what I need, except instead of creating a new workbook it creates new sheets within the template workbook.
Is there any change I can make to this to have it generate new workbooks?
Any help is much appreciated, I've never used macros before and anything I tried to change just breaks the code!
The code I found is below:
Sub Sample()
Dim wsToCopy As Worksheet, wsNew As Worksheet
With Sheets("Data")
LastRow = Sheets("Data").Cells(.Rows.Count, 1).End(xlUp).Row
For a = 1 To LastRow
Set wsToCopy = ThisWorkbook.Sheets("Template")
Set wsNew = ThisWorkbook.Sheets.Add
wsNew.Name = Sheets("Data").Cells(a, 1).Value
wsToCopy.Cells.Copy wsNew.Cells
Next
End With
End Sub
Create Workbooks From Template
Option Explicit
Sub CreateWorkbooksFromTemplate()
' Define constants.
Const LKP_NAME As String = "Data"
Const LKP_FIRST_CELL As String = "A2"
Const SRC_NAME As String = "Template"
Const DST_SUBFOLDER As String = "MyNewWorkbooks"
' Reference the source workbook.
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
' Determine the destination path.
Dim pSep As String: pSep = Application.PathSeparator
Dim dPath As String: dPath = swb.Path & pSep & DST_SUBFOLDER & pSep
' Create the destination folder if it doesn't exist.
If Len(Dir(dPath, vbDirectory)) = 0 Then MkDir dPath
' Write the values from the lookup column to an array.
Dim lws As Worksheet: Set lws = swb.Sheets(LKP_NAME)
Dim lfCell As Range: Set lfCell = lws.Range(LKP_FIRST_CELL)
Dim llCell As Range
Set llCell = lws.Cells(lws.Rows.Count, lfCell.Column).End(xlUp)
Dim lrg As Range: Set lrg = lws.Range(lfCell, llCell)
Dim lData(): lData = lrg.Value ' assumes at least two cells
' Reference the source worksheet.
Dim sws As Worksheet: Set sws = swb.Sheets(SRC_NAME)
' Copy the source worksheet to a new (single-worksheet) workbook.
sws.Copy
' Reference this new workbook, the destination workbook.
Dim dwb As Workbook: Set dwb = Workbooks(Workbooks.Count)
' Reference the only worksheet in the destination workbook,
' the destination worksheet.
Dim dws As Worksheet: Set dws = dwb.Sheets(1)
Dim lr As Long, dName As String
' Loop through the rows of the lookup array.
For lr = 1 To UBound(lData, 1)
' Store the current value in the lookup array as a string in a variable.
dName = CStr(lData(lr, 1))
' Check if the cell was not blank.
If Len(dName) > 0 Then ' cell was not blank
' Rename the destination worksheet.
dws.Name = dName
Application.DisplayAlerts = False ' overwrite without confirmation
' Save the destination workbook using the same name as the name
' of the destination worksheet, as a workbook without macros
' i.e. with an '.xlsx' extension.
dwb.SaveAs dPath & dName
Application.DisplayAlerts = True
'Else ' cell was blank; do nothing
End If
Next lr
' Finally, close the destination workbook.
dwb.Close SaveChanges:=False
' Inform.
MsgBox "Workbooks from template created.", vbInformation
End Sub
So I have a workbook with a macro, i will use the macro to open a different workbook called 'filename' once I have opened this 2nd workbook I will sum column AJ then with that value I would like to copy and paste the total value to cell C29 on the first workbook all in excel and VBA.
Sub vba_open_workbook()
Application.Calculation = xlCalculationAutomatic
filename = Range("G11")
Workbooks.Open filename
Workbooks(1).Activate
Range("C29") = Application.WorksheetFunction.Sum(Range("AJ:AJ"))
End Sub
Get Column Sum From Closed Workbook
Option Explicit
Sub AcquireSum()
'Application.Calculation = xlCalculationAutomatic ' ?
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Sheets("Sheet1") ' adjust!
Dim dCell As Range: Set dCell = dws.Range("C29")
Dim sFilePath As String: sFilePath = dws.Range("G11").Value
Dim swb As Workbook: Set swb = Workbooks.Open(sFilePath)
Dim sws As Worksheet: Set sws = swb.Sheets("Sheet1") ' adjust!
Dim sSum As Variant: sSum = Application.Sum(sws.Columns("AJ"))
swb.Close SaveChanges:=False ' it was just read from
If IsError(sSum) Then
MsgBox "Errors in column. Sum not acquired.", vbCritical
Exit Sub
End If
dCell.Value = sSum
MsgBox "Sum acquired.", vbInformation
End Sub
You should always use explicit referencing when using the Range-object.
If not: it refers to the active sheet. That means that your current code inserts ths sum on the same sheet from which it takes the values to be summed.
IMPORTANT: You have to replace the XXXX parts with the worksheet names of your workbooks.
Sub vba_open_workbook()
Application.Calculation = xlCalculationAutomatic
Dim rgSource As Range
Set rgSource = ThisWorkbook.Worksheets("XXXX").Range("AJ:AJ")
Dim Filename As String
Filename = Thisworkbook.Range("G11")
Dim wbTarget As Workbook
Set wbTarget = Workbooks.Open(Filename)
Dim rgTarget As Range
Set rgTarget = wbTarget.Worksheets("XXXX").Range("C29")
rgTarget.Value = Application.WorksheetFunction.Sum(rgSource)
End Sub
How do I make the space before the text disappear without making the space between the texts disappear on every sheet ? I've tried to come up with the following code.
Public Sub Test()
Dim rng As Excel.Range
For Each rng In ActiveSheet.UsedRange 'or change to something like ActiveSheet.Range("A1:A100") for a specific range
rng.Value2 = Trim(rng.Value2)
Next
End Sub
But it's really slow and will only apply to the first sheet out of my 3 sheets. Basically I want to change a cell like " Total Revenue" into "Total Revenue" and would like to apply my code on all 3 sheets I, B and C. Thank you guys in advance !
Trim Ranges
Basic
Note that this will convert any formulas to values.
Sub TrimAllWorksheetsBasic()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' or:
'Set wb = ActiveSheet.Parent ' workbook of the active sheet
Dim ws As Worksheet
For Each ws In wb.Worksheets
ws.UsedRange.Value = Application.Trim(ws.UsedRange.Value)
Next ws
End Sub
Only Cells With Values
Sub TrimAllWorksheets()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' or:
'Set wb = ActiveSheet.Parent ' workbook of the active sheet
Dim ws As Worksheet, rg As Range, arg As Range
For Each ws In wb.Worksheets
On Error Resume Next
Set rg = ws.UsedRange.SpecialCells(xlCellTypeConstants)
On Error Goto 0
If Not rg Is Nothing Then
For Each arg In rg.Areas
arg.Value = Application.Trim(arg.Value)
Next arg
Set rg = Nothing ' reset for the next iteration
End If
Next ws
End Sub
Specific Worksheets
Sub TrimSpecificWorksheets()
Dim TrimSheets(): TrimSheets = Array("I", "B", "C")
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' or:
'Set wb = ActiveSheet.Parent ' workbook of the active sheet
Dim ws As Worksheet, rg As Range, arg As Range
For Each ws In wb.Worksheets(TrimSheets)
On Error Resume Next
Set rg = ws.UsedRange.SpecialCells(xlCellTypeConstants)
On Error Goto 0
If Not rg Is Nothing Then
For Each arg In rg.Areas
arg.Value = Application.Trim(arg.Value)
Next arg
Set rg = Nothing ' reset for the next iteration
End If
Next ws
End Sub
I am trying to skip all of the sheets that are"xlSheetHidden" or "xlSheetVeryHidden". I have recently started using VBA to help speed up processes at my work when python wasn't allowing for what was needed. I currently have the following code:
Sub Merge_Sheets()
Dim Work_Sheets() As String
ReDim Work_Sheets(Sheets.Count)
For i = 0 To Sheets.Count - 1
Work_Sheets(i) = Sheets(i + 1).Name
Next i
Sheets.Add.Name = "Combined Sheet"
Dim Column_Index As Integer
Column_Index = Worksheets(1).UsedRange.Cells(1, 1).Column
Dim Row_Index As Integer
Row_Index = 0
For i = 0 To Sheets.Count - 2
Set Rng = Worksheets(Work_Sheets(i)).UsedRange
Rng.Copy
Worksheets("Combined Sheet").Cells(Row_Index + 1, Column_Index).PasteSpecial Paste:=xlPasteValues
Row_Index = Row_Index + Rng.Rows.Count + 1
Next i
Application.CutCopyMode = False
End Sub
I have tried inserting If .Visible = xlSheetVisible Then but cannot get it to work.
I have also tried to make it work with:
For Each Sheets In ActiveWorkbook.Worksheets
If Sheet.Visible = xlSheetVisible Then
However this still doesn't seem to work, any help would be greatly appreciated.
You did not use the for each correctly. In your code you loop over sheets with the name Sheets, then in the loop you refer to Sheet
For Each Sheets In ActiveWorkbook.Worksheets
If Sheet.Visible = xlSheetVisible Then '// Doesn't work!
So you probaby only needed to fix up this variable naming:
For Each ws In ActiveWorkbook.Worksheets
If ws.Visible = xlSheetVisible Then
Or
For Each sht In ActiveWorkbook.Worksheets
If sht.Visible = xlSheetVisible Then
sht and ws are traditional vba coding variable names for sheet/worksheet objects. But you can use any name you like. However, not Sheets as a variable name, as that is already the name of the built-in Sheets collection.
Merge (Append) Visible Worksheets
Option Explicit
Sub MergeWorksheets()
' Define constants.
Const dName As String = "Combined Sheet"
Const dFirstCellAddress As String = "A1"
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Application.ScreenUpdating = False
' Delete the destination worksheet ('dws') if it exists.
Dim dws As Worksheet
On Error Resume Next
Set dws = wb.Worksheets(dName)
On Error GoTo 0
If Not dws Is Nothing Then
Application.DisplayAlerts = False
dws.Delete
Application.DisplayAlerts = True
End If
' Write the number of worksheets to a variable ('swsCount').
Dim swsCount As Long: swsCount = wb.Worksheets.Count
' Add the names of all the visible worksheets
' to an array ('WorksheetNames').
' A better choice here is to use a collection or a dictionary
' where it is not important to know the number of elements (items).
' But no harm done.
Dim WorksheetNames() As String: ReDim WorksheetNames(1 To swsCount)
Dim sws As Worksheet ' Current Source Worksheet
Dim n As Long ' Visible Worksheets Count(er)
For Each sws In wb.Worksheets
If sws.Visible = xlSheetVisible Then
n = n + 1
WorksheetNames(n) = sws.Name
End If
Next sws
If n = 0 Then
MsgBox "No visible worksheets found.", vbExclamation
Exit Sub
End If
' Resize the array to the actual number of found visible worksheets
' (not necessary since later we're looping with 'For n = 1 to n').
If n < swsCount Then ReDim Preserve WorksheetNames(1 To n)
' Add and reference a new worksheet, the destination worksheet ('dws').
' First sheet...
Set dws = wb.Worksheets.Add(Before:=wb.Sheets(1))
' ... or e.g. last sheet
'Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
dws.Name = dName ' rename
' Reference the first cell of the destination range ('dfCell').
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim srg As Range ' Current Source Range
Dim drg As Range ' Current Destination Range
For n = 1 To n
' Reference the source worksheet.
Set sws = wb.Worksheets(WorksheetNames(n))
' Reference the used range in the source worksheet.
Set srg = sws.UsedRange
' Reference the destination range, the destination cell
' resized by the number of rows and columns of the source range.
Set drg = dfCell.Resize(srg.Rows.Count, srg.Columns.Count)
' Write the values from the source range to the destination range.
drg.Value = srg.Value
' Reference the next destination first cell.
Set dfCell = dfCell.Offset(srg.Rows.Count)
Next n
Application.ScreenUpdating = True
' Inform to not wonder if the code has run or not.
MsgBox "Worksheets merged.", vbInformation
End Sub
I have a tab called "Overview" where it asks me for the name of a project.
Once I write the project name, I want a macro to grab the project name, create a new tab, and change the name of the new tab to the project name.
Afterwards, I would like for the macro to go to another tab (let's call this tab "Template"), copy the whole worksheet, and paste the data into the newly created tab. I would like the formatting from the "Template" tab to flow to the new tab as well.
Sub AddNewTab()
Dim ws As Worksheet
Set ws = Worksheets("I DON'T KNOW WHAT TO WRITE HERE")
Rem Set working worksheets
Set WshSrc = ThisWorkbook.Worksheets("Source")
Set WshTrg = ThisWorkbook.Worksheets("Target")
'Create new tab based on project name
Sheets.Add(After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)).Name = Range("I2")
'Copy data from Template tab
Worksheets("Template").Range("A1:H12").Copy
Worksheets("I DON'T KNOW WHAT TO WRITE HERE").Range("A1").PasteSpecial
'hide gridlines in a worksheet with the project name
ws.Activate
ActiveWindow.DisplayGridlines = False
End Sub
Cell I2 in the "Overview" page is where the project name will be written.
Option Explicit
Sub AddNewTab()
Dim n As Long
With ThisWorkbook
n = .Sheets.Count
.Sheets("Template").Copy after:=.Sheets(n)
.Sheets(n + 1).Name = .Sheets("Overview").Range("I2")
End With
End Sub
Copy to a New Worksheet
Option Explicit
Sub AddNewTab()
Dim wb As Workbook: Set wb = ThisWorkbook
' Lookup
Dim lws As Worksheet: Set lws = wb.Worksheets("Overview")
Dim lCell As Range: Set lCell = lws.Range("I2")
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("Template")
Dim srg As Range: Set srg = sws.Range("A1:H12")
' Write the destination name to a variable.
Dim dName As String: dName = CStr(lCell.Value)
' Check if a sheet with the destination name already exists.
Dim dsh As Object ' also cover charts
On Error Resume Next
Set dsh = wb.Sheets(dName)
On Error GoTo 0
If Not dsh Is Nothing Then ' sheet already exists
MsgBox "A sheet with the name '" & dName & "' already exists.", _
vbCritical
Exit Sub
'Else ' sheet doesn't exist; do nothing
End If
' Add and rename the destination worksheet by using a variable
' (it automatically becomes the 'ActiveSheet').
Dim dws As Worksheet
Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
dws.Name = dName
' Copy the range.
srg.Copy dws.Range("A1")
ActiveWindow.DisplayGridlines = False
MsgBox "New worksheet added.", vbInformation
End Sub