I have been a silent reader on here for a few months but have been struggling with this code for a week now, so thought i would see if anyone can help.
I have a worksheet where sheet 1 contains information for users to input data.
Column A ask a question, column C is where the user will type in an answer.
Row 4 asks how many configurations there will be. depending on what number they input depends on how many cells light up to the right ie if 1 then D4 goes yellow, if 2 then D4 and E4 go yellow (using conditional formatting)
The user will then enter the title into the highlighted cell (D4,E4 ,F4 etc)
I want to create a new sheet at the end of the sheet for each configuration.
then NAME the new sheet by the text entered in D4, E4 etc.
the code I have so far is:
Option Explicit
Sub InsertSupplierSheet()
Dim ws As Worksheet
Dim tmpSht As Worksheet
Dim Lastcol As Integer, i As Integer, j As Integer
Dim DESCRANGE As Range
'~~> Change Sheet1 to the sheet which has all the data
Set ws = ThisWorkbook.Worksheets(1)
With ws
Lastcol = ActiveSheet.Cells(4, Columns.Count).End(xlToLeft).Column
If Lastcol < 4 Then Exit Sub
For i = 3 To Lastcol
If DoesSheetExist(ActiveSheet.Cells(4 & i).Value) Then
Set tmpSht = ActiveSheet.Cells(4 & i).Value
Else
Sheets.Add After:=Sheets(Sheets.Count)
Set tmpSht = ActiveSheet
tmpSht.Name = "NEWSHEET"
End If
.Rows("1:3").Copy tmpSht.Rows(1)
For j = 1 To 4
tmpSht.Columns(j).ColumnWidth = .Columns(j).ColumnWidth
Next j
.Rows(i).Copy tmpSht.Rows(4)
Next
End With
End Sub
Function DoesSheetExist(Sht As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(ws)
On Error GoTo 0
If Not ws Is Nothing Then DoesSheetExist = True
End Function
I put in "NEWSHEET" to see if even creates a new sheet, but it still fails. I just cant see where I am going wrong.
Any help /advise is welcomed.
EDIT .
I cant work out why though.
The last col will be H4 so lastcol would be "8" .
Then for i = 4 to 8 run the loop. there are descriptions in each of the cells in row 4 so i don't see why it would work for 2 instantness and then fail ?
I dont know if this would make it easier but I have the number of sheets i want to create in cell C4 so i could use this rather than looking up populated cells. so if C4 is 2 then I want to add 2 sheets named as the content of D4, E4. if C4 is 3 then I want to add 3 sheets names as content of D3,E3,F3. Am I making this harder than I need too ?
UPDATE
I figured out the copying over of info is affecting this loop. and amended the code to this.
Sub InsertSupplierSheet()
Dim ws As Worksheet
Dim tmpSht As Worksheet
Dim Lastcol As Integer, i As Integer, j As Integer
Dim DESCRANGE As Range
Dim sShtName As String 'Dimension sheet name variable
'~~> Change Sheet1 to the sheet which has all the data
Set ws = ThisWorkbook.Worksheets(1)
With ws
Lastcol = ActiveSheet.Cells(4, Columns.Count).End(xlToLeft).Column
If Lastcol < 4 Then Exit Sub
For i = 4 To Lastcol
sShtName = ActiveSheet.Cells(4, i).Value2 'Set sShtName to cell value within loop
If DoesSheetExist(sShtName) Then 'Use sShtName to call "Exists" function
Set tmpSht = Sheets(sShtName)
Else
Sheets.Add After:=Sheets(Sheets.Count)
Set tmpSht = ActiveSheet
tmpSht.Name = sShtName 'Change name to sShtName
End If
.Rows("1:3").Copy tmpSht.Rows(1)
.Rows(13).Copy tmpSht.Rows(4)
Next
End With
End Sub
Function DoesSheetExist(Sht As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(Sht)
On Error GoTo 0
If Not ws Is Nothing Then DoesSheetExist = True
End Function
this is doing what i want it to do with a couple of small exceptions.
the Sheets are being named by the cells in D1 , then E13,F13,G13,H13 So i need to figure out where that info is coming from.
the final bit is that due to my conditional formatting in the First sheet, I am getting text on black backgrounds in the copy cells, but that is the very least of my worries !
UPDATE
Found the error -
sShtName = ActiveSheet.Cells(4, i).Value2
should be
sShtName = Worksheets(1).Cells(4, i).Value2
You are calling your cells incorrectly. Use (4, i) instead of (4 & i).
The way you were calling it concatenated it to 43, which resulted in you checking cell AQ1 (AQ being the 43rd column) for the sheet reference.
Edit: I just walked through it a bit and found a couple of other errors. You need to set the sheet name to sht in your 'exists' function, and I'm assuming you want to set tmpSht to a sheet, so you need to encase it in sheets(). Try this:
Sub InsertSupplierSheet()
Dim ws As Worksheet
Dim tmpSht As Worksheet
Dim Lastcol As Integer, i As Integer, j As Integer
Dim DESCRANGE As Range
Dim sShtName As String 'Dimension sheet name variable
'~~> Change Sheet1 to the sheet which has all the data
Set ws = ThisWorkbook.Worksheets(1)
With ws
Lastcol = ActiveSheet.Cells(4, Columns.Count).End(xlToLeft).Column
If Lastcol < 4 Then Exit Sub
For i = 4 To Lastcol
sShtName = ActiveSheet.Cells(4, i).Value2 'Set sShtName to cell value within loop
If DoesSheetExist(sShtName) Then 'Use sShtName to call "Exists" function
Set tmpSht = Sheets(sShtName)
Else
Sheets.Add After:=Sheets(Sheets.Count)
Set tmpSht = ActiveSheet
tmpSht.Name = sShtName 'Change name to sShtName
End If
.Rows("1:3").Copy tmpSht.Rows(1)
For j = 1 To 4
tmpSht.Columns(j).ColumnWidth = .Columns(j).ColumnWidth
Next j
.Rows(i).Copy tmpSht.Rows(4)
Next
End With
End Sub
Function DoesSheetExist(Sht As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(Sht)
On Error GoTo 0
If Not ws Is Nothing Then DoesSheetExist = True
End Function
Instead of adding the new sheet and then setting the activesheet to the tmpsht you could use a shorter way (see below). And why did you set the ws if you don't use it....
Sub InsertSupplierSheet()
Dim ws As Worksheet
Dim tmpSht As Worksheet
Dim Lastcol As Integer, i As Integer, j As Integer
Dim DESCRANGE As Range
Set ws = ThisWorkbook.Worksheets(1)
With ws
Lastcol = .Cells(4, .Columns.Count).End(xlToLeft).Column
If (Lastcol < 4) Then
Exit Sub
End If
For i = 4 To Lastcol
If (DoesSheetExist(.Cells(4, i).Value2) = True) Then
Set tmpSht = Sheets(.Cells(4, i).Value)
Else
Set tmpSht = Sheets.Add After:=Sheets(Sheets.Count)
tmpSht.Name = "NEWSHEET"
End If
.Rows("1:3").Copy tmpSht.Rows(1)
For j = 1 To 4
tmpSht.Columns(j).ColumnWidth = .Columns(j).ColumnWidth
Next j
.Rows(i).Copy tmpSht.Rows(4)
Next i
End With
End Sub
Function DoesSheetExist(Sht As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(Sht)
On Error GoTo 0
If Not ws Is Nothing Then
DoesSheetExist = True
Else
DoesSheetExist = False
End If
End Function
This was my final code. There were a few tweaks, Firstly I added a formula in row 6 to shorten the name of row 4 to a 10 character name as I found the tab names were too long (hence the code for the naming refers to row 6. I also added some custom text to add into each sheet and some formatting
Option Explicit
Sub InsertSupplierSheet()
Dim ws As Worksheet
Dim tmpSht As Worksheet
Dim Lastcol As Integer
Dim i As Integer
Dim j As Integer
Dim DESCRANGE As Range
Dim sShtName As String 'Dimension sheet name variable
'~~> Change Sheet1 to the sheet which has all the data
Set ws = ThisWorkbook.Worksheets(1)
With ws
Lastcol = ActiveSheet.Cells(4, Columns.Count).End(xlToLeft).Column ' work with the template sheet
If Lastcol = 3 Then Exit Sub 'repeat these steps from the first config to the last
For i = 4 To Lastcol
sShtName = Worksheets(1).Cells(6, i).Value2 'Set sShtName to cell value within loop
If DoesSheetExist(sShtName) Then 'Use sShtName to call "Exists" function
Set tmpSht = Sheets(sShtName)
Else
Sheets.Add After:=Sheets(Sheets.Count)
Set tmpSht = ActiveSheet
tmpSht.Name = sShtName 'Change name to sShtName tmpSht.Name = sShtName
End If
.Rows("1:3").Copy tmpSht.Rows(1) ' Format the cell width in the new sheet
.Rows(13).Copy tmpSht.Rows(4)
tmpSht.Range("A1").Value = Worksheets(1).Cells(4, i).Value2
Range("A1").ColumnWidth = 30
Range("B1").ColumnWidth = 0
Range("C1").ColumnWidth = 30
Range("D1:K1").ColumnWidth = 10
Range("D4:J4").Font.Color = vbWhite ' format the colour of the text in the new sheet
Range("C1") = " " ' Negate info in cell C1
With Range("A1:M5") ' add borders
'Clear existing
.Borders.LineStyle = xlNone
'Apply new borders
.BorderAround xlContinuous
.Borders(xlInsideHorizontal).LineStyle = xlContinuous
.Borders(xlInsideVertical).LineStyle = xlContinuous
End With
With Range("A1:C4") ' set colours for the new sheet
.Font.Color = vbBlack
.Interior.Color = vbWhite
End With
Range("D4:J4").Font.Color = vbWhite ' set colour of the numbers to white to show on black background
Range("A5") = "Unit cost in " & Worksheets(1).Cells(17, 3).Value2
Range("A6") = "CUSTOM TEXT ONE."
Range("A7") = "NOTE if quantity " & Range("D4").Value2 + 5 & " is ordered then total cost will be your unit cost for " & Range("D4").Value2 & " multiplied by " & Range("D4").Value2 + 5 & " .This applies up to the quantity of " & Range("E4").Value2 - 1
Range("A8") = "CUSTOM TEXT 2"
Next i
End With
End Sub
Function DoesSheetExist(Sht As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(Sht)
On Error GoTo 0
If Not ws Is Nothing Then DoesSheetExist = True
End Function
Related
I am currently new to macro VBA and I have been trying to copy a column if the values of a specific rows are the same then paste it on another sheet until all columns are copied and pasted. The purpose of this is to consolidate team members of a team (the team is the value that im trying to look for). It only stops when the next cell to the right is already blank. And I will only find the team members' team on the first row of the sheet only. I placed a code that I found on the Internet and modified it but it only copies the last DATA team it finds. Thank you.
Dim ws As Worksheet
Dim aCell As Range, Rng As Range
Dim col As Long, lRow As Long
Dim colName As String
Set ws = ThisWorkbook.Sheets("Values")
With ws
Set aCell = .Range("A1:XFD1").Find(What:="DATA", LookIn:=xlValues, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
aCell.EntireColumn.Cut
Sheets("Team").Columns("D:W").Insert Shift:=xlToRight
Else
MsgBox "Team not found"
End If
End With
You can try this.
Option Explicit
Sub CopyCols()
Dim ArrTeams() As String, Team As String
Dim TeamCounter As Long, LastCol As Long, FirstCol As Long, i As Long, LastColDest As Long
Dim SrcWs As Worksheet
Dim Wb As Workbook
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set Wb = ThisWorkbook
Set SrcWs = Wb.Sheets("Sheet1")
ReDim ArrTeams(1 To 1)
With Wb
With SrcWs
'find last column with team
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
TeamCounter = 1
FirstCol = 1 'or whatever your first column with teams is
'loop all columns in row 1
For i = FirstCol To LastCol
If .Cells(1, i) <> "" Then
Team = .Cells(1, i)
If Not IsInArray(Team, ArrTeams) Then 'take only unique team names
ReDim Preserve ArrTeams(1 To TeamCounter)
ArrTeams(TeamCounter) = Team
TeamCounter = TeamCounter + 1
End If
End If
Next i
End With
'create new sheet for each team
For i = 1 To UBound(ArrTeams)
.Sheets.Add after:=.Sheets(.Sheets.Count)
.Sheets.Item(.Sheets.Count).Name = ArrTeams(i)
Next i
With SrcWs
'loop all columns in row 1
For i = FirstCol To LastCol
If .Cells(1, i) <> "" Then
Team = .Cells(1, i)
With Wb.Sheets(Team)
'find last non empty column on destination sheet
LastColDest = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
.Cells(1, i).EntireColumn.Copy
Wb.Sheets(Team).Cells(1, LastColDest + 1).PasteSpecial
End If
Next i
End With
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Public Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function
It should loop all columns on "Sheet1" starting in FirstCol and ending in LastCol, take unique team names from first row. Create new sheet for each unique team name. Copy entire column for each unique team name to coresponding sheet.
Just remember that it will allways add new sheets so if you want to run it multiple times then there should be check if sheet with specific name already exists.
EDIT
Add
Dim LastRow As Long, j As Long
And
Dim TargetWs As Worksheet
in declaration part at begining
Change loop for adding new sheets to
For i = 1 To UBound(ArrTeams)
.Sheets.Add after:=.Sheets(.Sheets.Count)
.Sheets.Item(.Sheets.Count).Name = ArrTeams(i)
.Sheets(ArrTeams(i)).Range("A2:A1000").FormulaR1C1 = _
"=SUM(RC[2]:RC[" & .Sheets(ArrTeams(i)).Columns.Count - 1 & "])"
Next i
at the end add
For i = LBound(ArrTeams) To UBound(ArrTeams)
Team = ArrTeams(i) 'team name and also sheet name
Set TargetWs = .Sheets(Team)
With TargetWs
.Calculate 'calculate SUM formula on each sheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in column "A"
For j = LastRow To 2 Step -1 'assuming that in row 1 there is some header
If .Cells(j, "A") = 0 Then
.Cells(j, "A").EntireRow.Delete
End If
Next j
End With
Next i
This should do the trick as long as you don't have more than 1000 rows of data. If so you can adjust SUM formula to cover more rows or find last row with data on each "Team" sheet and adjust formula in loop.
Hi #Sphinx this is what I have so far. And I modified the code you have given and added something to it. The syntax that I do not have is on how to delete a row when a specific cell on column C has 0 value. And it should work on all ArrTeams(i) sheets only. Thank you for you help.
https://i.stack.imgur.com/M8NS8.png
Option Explicit
Sub CopyCols()
Dim ArrTeams() As String, Team As String
Dim TeamCounter As Long, LastCol As Long, FirstCol As Long, i As Long, LastColDest As Long
Dim SrcWs As Worksheet
Dim Wb As Workbook
Dim LastRowColumnD As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set Wb = ThisWorkbook
Set SrcWs = Wb.Sheets("Values")
ReDim ArrTeams(1 To 1)
With Wb
With SrcWs
'find last column with team
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
TeamCounter = 1
FirstCol = 1 'or whatever your first column with teams is
'loop all columns in row 1
For i = FirstCol To LastCol
If .Cells(1, i) <> "" Then
Team = .Cells(1, i)
If Not IsInArray(Team, ArrTeams) Then 'take only unique team names
ReDim Preserve ArrTeams(1 To TeamCounter)
ArrTeams(TeamCounter) = Team
TeamCounter = TeamCounter + 1
End If
End If
Next i
End With
'create new sheet for each team
For i = 1 To UBound(ArrTeams)
.Sheets.Add After:=.Sheets(.Sheets.Count)
.Sheets.Item(.Sheets.Count).Name = ArrTeams(i)
Sheets("Values").Columns("A:C").Copy
ActiveSheet.Paste Destination:=Worksheets(ArrTeams(i)).Range("A1:C1")
Range("A1").Value = " "
Range("B1").Value = " "
Range("C1").Value = " "
Range("A2").Value = "Team:"
Range("B2").Value = ArrTeams(i)
Range("C2").Value = " "
Range("B2").HorizontalAlignment = xlCenter
Range("B2").VerticalAlignment = xlCenter
Range("A2").HorizontalAlignment = xlCenter
Range("A2").VerticalAlignment = xlCenter
LastRowColumnD = Cells(Rows.Count, 1).End(xlUp).Row
Range("C4:C" & LastRowColumnD).Formula = "=sum(D4:XFD4)"
Next i
With SrcWs
'loop all columns in row 1
For i = FirstCol To LastCol
If .Cells(1, i) <> "" Then
Team = .Cells(1, i)
With Wb.Sheets(Team)
'find last non empty column on destination sheet
LastColDest = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
.Cells(1, i).EntireColumn.Copy
Wb.Sheets(Team).Cells(1, LastColDest + 1).PasteSpecial
End If
Next i
End With
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Public Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function
I am attempting to write code that runs through column G, and adds a new sheet for every unique value with out creating duplicates; However from what I have so so it creates duplicates
Public Sub AddSheet()
Worksheets("Dataset").Select
Range("A1", Range("A1").End(xlToRight)).Name = "Title"
Range("A2", Range("G1").End(xlDown)).Name = "Data"
Range("H2", Range("H1").End(xlDown)).Name = "Physician"
Dim i As Integer, lastrow As Integer
lastrow = Worksheets("Dataset").Cells(Worksheets("Dataset").Rows.Count, "H").End(xlUp).Row
With Range("Physician")
For i = 1 To lastrow
If i.Value = Worksheetexists = False Then
Sheet.Add
ActiveSheet.Name = Worksheets("Dataset").Cells(i, 1).Value
Else
GoTo NextStep:
End If
Next
End With
End Sub
something like this will iterate and create a new sheet for every unique value in Column A.
Public Sub AddSheet()
With Worksheets("Dataset")
Dim lastrow As Long
lastrow = .Cells(.Rows.Count, "H").End(xlUp).Row
Dim i As Long
For i = 1 To lastrow
If IsError(Application.Evaluate("'" & .Cells(i, 1).Value & "'!A1")) And .Cells(i, 1) <> "" Then
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets.Add
ws.Name = .Cells(i, 1).Value
End If
Next i
End With
End Sub
Something like this should work and be a bit safer as you may need to check the edge case that a sheet you are adding already exists. I'm using a dictionary to keep track of unique sheet names first, then adding to that based on the unique values in column H.
Sub SOExample()
Dim DataSheet As Excel.Worksheet
Dim ws As Excel.Worksheet
Dim lastRow As Long
Dim i As Long
Dim dict As Object
Dim SheetName As String
Set dict = CreateObject("Scripting.Dictionary")
Set DataSheet = ThisWorkbook.Worksheets("Dataset")
lastRow = DataSheet.Cells(DataSheet.Rows.Count, "H").End(xlUp).Row
'Add existing sheets into the dictionary first
'in case a sheet already exists with that name
For Each ws In ThisWorkbook.Worksheets
dict.Add ws.Name, ws.Name
Next
'Loop the range and add new sheets
For i = 1 To lastRow
SheetName = DataSheet.Cells(i, 8).Value 'Column H is index 8
If Not dict.exists(SheetName) Then
dict.Add SheetName, SheetName
Set ws = ThisWorkbook.Worksheets.Add
ws.Name = SheetName
End If
Next
End Sub
I got stuck in the below-mentioned code, what I want to do is to get the value from Range("C4:C" & LastRow) in worksheets X2 that will b changing every time and compare each value with all open workbooks name. If match found then search that value in A column of worksheet X1 and copy all those rows.
The final objective is to paste those rows into those open workbooks which have the same value. For eg: Range C4 has TW00 then the code will search workbooks which have name "TW00.xlsx" and copy all the rows from worksheet X1 which have TW00 value in column A in the worksheet named TW00.xlsx.
Dim BookNames()
ReDim BookNames(Windows.Count)
n = 1
For n = 1 To Windows.Count
BookNames(n) = Workbooks(n).Name
If Workbooks(n).Name = Workbooks("A.xlsx").Worksheets("X2").Range("C4:C" & LastRow).Value Then
Set Rng = Workbooks("A.xlsx").Worksheets("X1").Range("A2:A50000")
For Each c In Rng.Cells
If c.Value = Workbooks("A.xlsx").Worksheets("X2").Range("C4").Value Then
If Not CopyRng Is Nothing Then
Set CopyRng = Application.Union(CopyRng,
Workbooks("A.xlsx").Worksheets("X1").Rows(c))
Else
Set CopyRng = Workbooks("A.xlsx").Worksheets("X1").Rows(c)
End If
End If
Next c
CopyRng.Copy
Workbooks(n).Activate
Worksheets.Add
ActiveSheet.Name = "X1"
ActiveSheet.Paste
End If
Next n
is that code help you?
Sub test()
Dim lastRow As Long
dim sheetName as string
Dim sourceDataSheet As worksheet
Dim sourceSheetsName as worksheet
dim targetDataSheet as worksheet
Dim wkb As Variant
set sourceDataSheet = ActiveWorkbook.Worksheets("X2")
set sourceSheetsName = ActiveWorkbook.Worksheets("X1")
With sourceSheetsName
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
sheetName = .Cells(lastRow, "A")
For Each wkb In Application.Workbooks
If wkb.Name <> .Name And wkb.Name = sheetName Then
set targetDataSheet = wkb.Worksheets.Add
with sourceDataSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
for i = 1 to lastRow
if .Cells(i, "A").Value = sheetName then
.Cells(i, "A").EntireRow.Copy
targetDataSheet.Cells(i, "A").PasteSpecial Paste:=xlPasteValues
end if
next i
end with
End If
Next wkb
End With
End Sub
I want to find empty cells and copy there values:
Values: "10/11/2017" and "Yes" should be copied to row 7 (colB & colC).
What I have:
Sub add_value()
Dim wbA As Workbook
Dim wsA As Worksheet
Set wbA = ActiveWorkbook
Set wsA = wbA.Worksheets("Sheet1")
Dim nrow As Long
nrow = 6
Do Until wsA.Range("B" & nrow).Value = ""
wsA.Range("B" & nrow).Value = wsA.Range("B3").Value
wsA.Range("C" & nrow).Value = wsA.Range("C3").Value
Exit Sub
nrow = nrow + 1
Loop
End Sub
Something is wrong with my loop and I don't know how to fix it.
No need to loop through your rows until you find an empty one. You can replace the entire sub with this:
Sub add_value()
With ThisWorkbook.Worksheets("Sheet1")
.Cells(.Rows.Count, "B").End(xlUp).Offset(1, 0).Resize(1, 2).Value = .Range("B3:C3").Value
End With
End Sub
As per your comments, to also add borders you can reorganise the code a bit like this:
Sub add_value()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
With ws.Cells(ws.Rows.Count, "B").End(xlUp).Offset(1, 0).Resize(1, 2)
.Value = ws.Range("B3:C3").Value
.Borders(xlEdgeLeft).LineStyle = xlContinuous
End With
End Sub
I would have done something like this:
Sub FindFirstEmptyValue()
Dim lastRow As Long
With Worksheets("Sheet1")
lastRow = .Cells(.Rows.Count, 2).End(xlUp).Row + 1
.Cells(lastRow, 2) = .Range("B3").value
.Cells(lastRow, 3) = .Range("C3").value
End With
End Sub
It gives you the last row, you increment it with 1 and on this row you write the B3 and C3 values.
I'm trying to delete all cells with strikethrough from a Workbook and iterate on all sheets at the same time.
I have followed this, this and this and come up with two macros, but they are not working. This is the first time that I use VBA so I'm not sure of how to fix these problems.
Sub DeleteCells()
Dim Cell As Range, iCh As Integer, NewText As String
Dim WS_Count As Integer
Dim I As Integer
' Set WS_Count equal to the number of worksheets in the active
' workbook.
WS_Count = ActiveWorkbook.Worksheets.Count
' Begin the loop.
For I = 1 To WS_Count
With Sheets(I) ' <~~ avoid select as much as possible, work directly with the objects
Lrow = .Cells(.Rows.Count, "C").End(xlUp).Row
For Each Cell In .Range("C1:M" & Lrow)
For iCh = 1 To Len(Cell)
With Cell.Characters(iCh, 1)
If .Font.Strikethrough = False Then NewText = NewText & .Text
End With
Next iCh
Cell.Value = NewText ' <~~ You were doing it the other way around
NewText = "" ' <~~ reset it for the next iteration
Cell.Characters.Font.Strikethrough = False
Next Cell
End With
Next I
End Sub
In this case I get "Unable to get the Text property of the Character class"
Sub LoopThroughAllTablesinWorkbook()
Dim tbl As ListObject
Dim sht As Worksheet
For Each sht In ThisWorkbook.Worksheets
With Sheets("sht")
Lrow = .Cells(.Rows.Count, "C").End(xlUp).Row
For Each Cell In .Range("C1:M" & Lrow)
For iCh = 1 To Len(Cell)
With Cell.Characters(iCh, 1)
If .Font.Strikethrough = False Then NewText = NewText & .Text
End With
Next iCh
Cell.Value = NewText ' <~~ You were doing it the other way around
NewText = "" ' <~~ reset it for the next iteration
Cell.Characters.Font.Strikethrough = False
Next Cell
End With
Next sht
End Sub
In this case I get as an error: Subscript out of range, which refers to the With Sheets part.
Try this
Sub DeleteCells()
Dim cel As Range
Dim ws As Worksheet
Dim lastRow As Long
For Each ws In ActiveWorkbook.Worksheets 'loop through all sheets
With ws
lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row 'get last row with data using Column C
For Each cel In .Range("C1:M" & lastRow) 'loop through all cells in range
If cel.Font.Strikethrough Then 'check if cell has strikethrough property
cel.Clear 'make cell blank and remove strikethrough property
End If
Next cel
End With
Next ws
End Sub