I have the VBA code setup to delete rows, format columns, add a heading, etc. Now I need this code to be repeated on each Sheet in the Workbook. Some Workbooks will have 1 sheet, some could have dozens. I've looked at various answers, but can't find something that works.
Here is a snippet of the code I need to have repeated on each sheet:
Sub C_FormattingWTitle_Step3_do_on_each_tab()
'Delete all blank empty rows
Dim FirstBlankCell As Long, rngFound As Range
With ActiveSheet
Set rngFound = .Columns("G:G").Find("*", After:=.Range("G1"), searchdirection:=xlPrevious, LookIn:=xlValues)
If Not rngFound Is Nothing Then FirstBlankCell = rngFound.Row
End With
If ActiveCell.SpecialCells(xlLastCell) <> rngFound Then
Selection.SpecialCells(xlCellTypeBlanks).Select
ActiveWindow.SmallScroll Down:=9
Selection.EntireRow.Delete
Else
Range("A1").Select
End If
'Remove all not 260563 or header in SiteID column
Dim LR As Long, i As Long
LR = Range("G" & Rows.Count).End(xlUp).Row
For i = LR To 2 Step -1
If Not (Range("G" & i).Value Like "260563") And Not (Range("G" & i).Value Like "SiteID") Then Rows(i).Delete
Next i
'Remove all False values and header in Sign in Success column
Dim FR As Long, p As Long
FR = Range("F" & Rows.Count).End(xlUp).Row
For p = FR To 2 Step -1
If Not (Range("F" & p).Value Like True) And Not (Range("F" & p).Value Like "SignInSuccess") Then Rows(p).Delete
Next p
'Remove shading and formatting from header row
Rows("1:1").Select
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'Format date/time
Columns("A:A").Select
Selection.NumberFormat = "m/d/yyyy hh:mm:ss;#"
After the code is run on every sheet, I want to insert Save As code. Any help would be greatly appreciated.
Use a separate sub to call and execute that subroutine:
Dim wkst As Worksheet
For Each wkst In ActiveWorkbook.Worksheets
Call C_FormattingWTitle_Step3_do_on_each_tab(wkst)
Next
Related
How can i create code which will repeating code until columna a value will be empty
this is my code.
Sheets("sheet4").Select
Sheets("sheet4").Range("$A$1:$AG$2336").AutoFilter Field:=1, Criteria1:= _
Sheets("sheet1").Range("a3")
Sheets("sheet4").Range("a1:ad1").find(Sheets("sheet1").Range("L3").Value).offset(2, 0).Select
Do Until ActiveCell.EntireRow.Hidden = False
ActiveCell.offset(2, 0).Select
Loop
Selection.Copy Sheets("sheet1").Range("b3")
Sheets("sheet1").Select
End Sub
I need to copy my selection down until column a will end ( i mean cell in column a will be empty). Can u please help me ??
Replace the 3 with a variable and put the code in a loop.
Option Explicit
Sub macro()
Dim wb As Workbook
Dim ws1 As Worksheet, ws4 As Worksheet
Dim colA, colL, iRow As Long
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("Sheet1")
Set ws4 = wb.Sheets("Sheet4")
ws4.Select
iRow = 3
colA = ws1.Cells(iRow, "A")
Do While Len(colA) > 0
colL = ws1.Cells(iRow, "L")
If Len(colL) > 0 Then
' apply filter
ws4.Range("A1:AG2336").AutoFilter Field:=1, Criteria1:=colA
' copy filtered data
ws4.Range("A1:AD1").Find(colL).Offset(2, 0).Select
Do Until ActiveCell.EntireRow.Hidden = False
ActiveCell.Offset(2, 0).Select
Loop
Selection.Copy ws1.Range("B" & iRow)
'
End If
' next value in col A
iRow = iRow + 1
colA = ws1.Cells(iRow, "A")
Loop
MsgBox iRow - 3 & " rows scanned on " & ws1.Name, vbInformation
End Sub
I have to generate a spreadsheet of upcoming events, and I use a macro that creates a thick line that separates each date from the one above it. It's based on the value change in the "Date" column". However, sometimes I have to filter the data by another criteria (say, the county). In those cases, the offset macro I've been using doesn't always work, as the data that changes and produces the line is in a hidden row, and therefore the line is as well. Can anyone help?
I've tried various ways of defining the range as active cells only, but I don't think I'm doing it correctly.
The macro I'm using is as follows, without applying to hidden rows:
Sub UpcomingLines()
Application.ScreenUpdating = False
Dim LastRow As Long
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim rng As Range
For Each rng In Range("A1:A100" & LastRow)
If rng <> rng.Offset(1, 0) Then
Range("A" & rng.Row & ":H" & rng.Row).Borders(xlEdgeBottom).Weight = xlThick
End If
Next rng
Application.ScreenUpdating = True
End Sub
I've tried integrating SpecialCells like this:
Sub UpcomingLines()
Application.ScreenUpdating = False
Dim LastRow As Long
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim rng As Range
Set myrange = Range("A1:H" & Cells(Rows.Count, "A").End(xlUp).Row).SpecialCells(xlCellTypeVisible)
For Each rng In Range("A1:A100" & LastRow)
If rng <> rng.Offset(1, 0) Then
Range("A" & myrange.Row & ":H" & rng.Row).Borders(xlEdgeBottom).Weight = xlThick
End If
Next rng
Application.ScreenUpdating = True
End Sub
However, this generates lines in places I don't want them -- basically, the show up between date changes, but also everyplace there is a hidden row, even if there is no date change before or after the hidden row.
Try something like this:
Sub UpcomingLines()
Dim ws As Worksheet, LastRow As Long, c As Range, theDate
Application.ScreenUpdating = False
Set ws = ActiveSheet
ws.Range("A1").CurrentRegion.Borders.LineStyle = xlNone 'remove existing borders
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
theDate = 0
For Each c In ws.Range("A2:A" & LastRow).SpecialCells(xlCellTypeVisible)
'different date from previous visible row?
If c.Value <> theDate Then
'add border to top of row if not the first change
If theDate <> 0 Then c.Resize(1, 8).Borders(xlEdgeTop).Weight = xlThick
theDate = c.Value 'remember this date
End If
Next c
Application.ScreenUpdating = True
End Sub
i'm trying to make some changes in excel file using VBA, the file contains many sheets
the code should make changes for 1st sheet then go to the next and next,
but after makes the changes in 1st sheet and go to 2nd it shows:
Error no 1004 "Object error".
Here the code:
Sub AddRefNo()
'This code adds Reference Number to All BOQ sheets based on Worksheet Name
'select the first sheet
Worksheets(4).Select
' Work in One Sheet
Do While ActiveSheet.Index < Worksheets.Count
'add new Column
'the error happens here
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").Select
ActiveCell.FormulaR1C1 = "Ref. No"
Range("A2").Select
'Find Sheet Name
MySheet = ActiveSheet.Name
'creat numbering system
Dim Noe As String
Noe = 0
' Find the last row
Dim LastRow As Integer
LastRow = Range("E" & Rows.Count).End(xlUp).Row
Range("E2").Select
'repeat steps to the last row
Do While ActiveCell.Row < LastRow
'checking if the cell is not blank
Do While ActiveCell.Value <> ""
ActiveCell.Offset(0, -4).Select
Noe = Noe + 1
ActiveCell.Value = MySheet & " - " & Noe
ActiveCell.Offset(0, 4).Select
ActiveCell.Offset(1, 0).Select
Loop
ActiveCell.Offset(1, 0).Select
Loop
Noe = 0
Range("A1").Select
ActiveSheet.Next.Select
Loop
Worksheets(1).Select
End Sub
Here is a way to reliable loop through your worksheet index numbers:
Sub AddRefNo()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet
Dim x As Long
For x = 4 To wb.Worksheets.Count - 1
Set ws = wb.Worksheets(x)
'Your code to work with ws as a parent
Next x
End Sub
This should do the trick if you want to loop from sheet 4:
Option Explicit
Sub AddRefNo()
'Declare a worksheet variable
Dim ws As Worksheet
'Loop every sheet in the workbook
For Each ws In ThisWorkbook.Worksheets
If ws.Index < 4 Or ws.Index = ThisWorkbook.Worksheets.Count Then GoTo nextWorksheet
'Reference always the sheet
With ws
'Calculate last row
Dim LastRow As Long
LastRow = .Cells(.Rows.Count, "E").End(xlUp).Row
'Insert a column
.Range("A:A").Insert
.Range("A1") = "Ref. No"
'Put the name sheet + reference starting from 1
With .Range("A2:A" & LastRow)
.FormulaR1C1 = "=" & Chr(34) & ws.Name & Chr(34) & "&ROW(RC)-1"
.Value = .Value
End With
End With
nextWorksheet:
Next ws
End Sub
My process consists:
Going through the cell values in Column A of sheet 1
Checking to see if the cell values from sheet 1 match with any of the values in Column C of sheet 2
If there is a match, copy the entire row in which there is a match from Sheet 2 to Sheet 3.
I posted my code below but somehow can't get it to work.
Sub Test1()
Dim Name As String
Dim lastrow As Long
Dim Cell As Variant
lastrow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastrow
Name = Cells(i, 1)
If Name <> "" Then
For Each Cell In Sheets("Sheet2").Range("C2:C4000")
If Cell.Value = Name Then
matchRow = Cell.Row
Rows(matchRow & ":" & matchRow).Select
Selection.Copy
Sheets("Sheet3").Select
ActiveSheet.Rows(matchRow).Select
ActiveSheet.Paste
Sheets("Sheet2").Select
End If
Next
End If
Next
End Sub
No need to loop through every cell in Sheet2!C:C.
Sub Test1()
Dim i As Long, c as variant
With Worksheets("Sheet1")
For i = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
c = Application.Match(.Cells(i, "A").Value2, Worksheets("Sheet2").Columns(3), 0)
If Not IsError(c) Then
Worksheets("Sheet2").Rows(c).Copy _
Destination:=Worksheets("Sheet3").Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0)
End If
Next i
End With
End Sub
You need to get the .Value of the cell.
Name = CStr(Cell(i, 1).Value)
Also, there is a built in function to determine if a cell is empty.
If Not IsEmpty(Cell(i, 1).Value) Then
Also, I would suggest setting a reference to the worksheet instead of just saying Cells()
Dim ws As Worksheet
Set ws = Excel.Application.ThisWorkbook.Worksheets("wb name here")
ws.Cells(i, 1).Value
Hope this helps!
Where your errors were coming from was it was getting confused what sheet was selected. So you needed to be more explicit, as below.
Sub Test1()
Dim Name As String
Dim lastrow As Long
Dim Cell As Variant
lastrow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastrow
Name = Sheets("Sheet1").Cells(i, 1)
If Name <> "" Then
For Each Cell In Sheets("Sheet2").Range("C2:C4000")
If Cell.Value = Name Then
matchRow = Cell.Row
Sheets("Sheet2").Select
ActiveSheet.Rows(matchRow).Select
Selection.Copy
Sheets("Sheet3").Select
ActiveSheet.Rows(matchRow).Select
ActiveSheet.Paste
Sheets("Sheet2").Select
End If
Next
End If
Next
End Sub
I think this photo should pretty much tell you what I am trying to achieve.
I can still try to explain bit.
I have on top table 5 column A B C D E
Column A is main it contains Num with record for individual numbers it can have up to 8 records.
I need to put all record in 1 line by NUM.
it is sort by A and D.
I just need to move column C based on time it occurred.
I just added extra column because I can have up to 8 Non Created and upto 4 Cause Created record.
I am assuming the follwoing
The Table one is in Sheet called "Input"
The output will be generated in Sheet called "output" which already have the headers in place
Paste this code in a module and run it
Option Explicit
Sub Sample()
Dim wsInput As Worksheet, wsOutput As Worksheet
Dim wsILrow As Long, wsOLrow As Long, i As Long, c As Long, nc As Long
Dim wsIrng As Range, fltrdRng As Range, cl As Range
Dim col As New Collection
Dim itm
Set wsInput = Sheets("Input")
Set wsOutput = Sheets("Output")
With wsInput
wsILrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set wsIrng = .Range("A1:E" & wsILrow)
With wsIrng
.Sort Key1:=.Range("A2"), Order1:=xlAscending, Key2:=.Range("D2") _
, Order2:=xlAscending, Header:=xlYes, OrderCustom:=1, MatchCase:=False _
, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2:= _
xlSortNormal
End With
For i = 2 To wsILrow
On Error Resume Next
col.Add .Cells(i, 1).Value, Chr(34) & .Cells(i, 1).Value & Chr(34)
On Error GoTo 0
Next i
End With
wsOLrow = 2
With wsOutput
For Each itm In col
.Cells(wsOLrow, 1).Value = itm
wsOLrow = wsOLrow + 1
Next
wsOLrow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 2 To wsOLrow
With wsInput
'~~> Remove any filters
.AutoFilterMode = False
With wsIrng '<~~ Filter, offset(to exclude headers)
.AutoFilter Field:=1, Criteria1:=wsOutput.Cells(i, 1).Value
Set fltrdRng = .Offset(1, 0).SpecialCells(xlCellTypeVisible)
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
'<~~ c is for Cause column and nc is for non cause
c = 3: nc = 7
For Each cl In fltrdRng.Cells
If cl.Column = 3 And Len(Trim(cl.Value)) <> 0 Then
If InStr(1, cl.Value, "Cause", vbTextCompare) Then
.Cells(i, c).Value = wsInput.Cells(cl.Row, 3).Value
c = c + 1
ElseIf InStr(1, cl.Value, "Non", vbTextCompare) Then
.Cells(i, nc).Value = wsInput.Cells(cl.Row, 3).Value
nc = nc + 1
End If
.Cells(i, 2).Value = wsInput.Cells(cl.Row, 2).Value
.Cells(i, 15).Value = wsInput.Cells(cl.Row, 5).Value
End If
Next
Next i
End With
End Sub
Screenshot
Input Sheet
Output Sheet
Note: Any future changes to the structure has to be incorporated in the code as well.