VBA - put value in each empty row created - vba

I have a vba code that creates empty row after each row with value:
Row 1
Row 2
Row 3
Output
Row 1
Row 2
Row 3
In the empty rows I want to insert value "check1", "check2", the auto increment of "check" and "autonumber"
To get a final output of the below:
Row 1
check1
row 2
check2
row n
check n
here is the code I have started:
Sub Insert_Blank_Rows()
'Select last row in worksheet.
Selection.End(xlDown).Select
Do Until ActiveCell.Row = 1
'Insert blank row.
ActiveCell.EntireRow.Insert shift:=xlDown
'Move up one row.
ActiveCell.Offset(-1, 0).Select
Loop
End Sub

Here's a quick and easy and efficient way with only minimal adjustment to your current code.
Sub Insert_Blank_Rows()
Dim rng as Range
Set rng = Selection ' grab top most cell in range, you may want to actually refer to the actual cell.
rng.End(xlDown).Select 'Select last row in worksheet.
Do Until ActiveCell.Row = 1
'Insert blank row.
ActiveCell.EntireRow.Insert shift:=xlDown
'Move up one row.
ActiveCell.Offset(-1, 0).Select
Loop
'fill blanks with incremental checks
Dim rngBottom as Range
Set rngBottom = Cells(rows.Count,rng.Column).End(xlUp).Offset(1)
Range(rng, rngBottom).SpecialCells(xlCellTypBlanks).FormulaR1C1 = "=""Check""&ROW()/2"
End Sub

I'll throw in this solution, with no looping nor inserting
it's very fast (less than 1 second for 20k rows)
Option Explicit
Sub main()
Dim helperCol As Range
With ActiveSheet.UsedRange
Set helperCol = .Columns(.Columns.Count + 1)
End With
With Range(ActiveCell, ActiveCell.End(xlDown))
.Offset(, helperCol.Column - .Column).Formula = "=ROW()"
With .Offset(.Rows.Count)
.Formula = "=CONCATENATE(""check"",ROW()-" & .Rows.Count & ")"
.Value = .Value
With .Offset(, helperCol.Column - .Column)
.Formula = "=ROW()-" & .Rows.Count & "+ 0.1"
.Value = .Value
End With
End With
.Resize(2 * .Rows.Count, helperCol.Column - .Column + 1).Sort Key1:=helperCol.Resize(2 * .Rows.Count), Header:=xlNo
helperCol.Resize(2 * .Rows.Count).Clear
End With
End Sub
as per OP's request, it takes move from ActiveCell

So every other row is empty and you want to fill it? One way would be something like
finalRow = cells(1000000,1).end(xlup).row
yourIncrement = 1
for i = 1 to finalRow
if isempty(cells(i,1)) then
cells(i,1) = "check" & yourIncrement
yourIncrement = yourIncrement + 1
end if
next i
I am assuming your want to fill column 1 (A).

How's this?
Sub Insert_Blank_Rows()
Dim lastRow&, i&
'Assuming column A has the most data (if not change the `1` to whatever column # does have the most data
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
'Select last row in worksheet.
'Selection.End(xlDown).Select ' Don't use `.Select`
i = 2
Do While i <= lastRow
Rows(i).Select
Rows(i).EntireRow.Insert shift:=xlDown
Cells(i, 1).Value = "Check " & Cells(i - 1, 1).Value
Cells(i, 1).Value = Cells(i, 1).Value
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
i = i + 2
Loop
End Sub

Here, I got one for you. I already tested it and work well for requirement.
Which is special in my code? My code will miss no row. Perfect auto-increment.
And I also reference from BruceWayne's code because I don't want to edit his own code.
Sub checkingData()
Dim exeRow As Integer 'For indexing the executing row
Dim lastRow As Integer 'For storing last row
exeRow = 2 'Checking from first row
'Assume that First Column has more data row than Other Column
lastRow = Cells(Rows.Count, 1).End(xlUp).row
'Loop from First Row to Last Row
Do While exeRow <= lastRow + 1
'Select data row
Rows(exeRow).Select
'Insert row below data row
Rows(exeRow).EntireRow.Insert shift:=xlDown
'Set auto-increment result
Cells(exeRow, 1) = "Check " & (exeRow / 2)
'Increase lastRow count because of adding blank row
lastRow = lastRow + 1
'Go to next data row
exeRow = exeRow + 2
Loop
End Sub

Related

VBA Add loop to add three rows and text below each populated cell

enter image description hereI'm trying to create a "Loop While" macro to work down column B in an excel file and if the cell is populated, then add three rows after, along with specific text. Once the rows are added, continue down to the next row and if the cell is populated, then add three rows below that cell. Continue down column until a blank cell is reached
I've tried simple Do While loop but not able to add rows or additional text
The text you want to add is the third line. find the last line with values, then loop backwards.
Sub moveandplace()
Dim textArr() As Variant
textArr = Array("Test1", "Test2", "Test3") 'change to your desired text.
With Worksheets("Sheet1") 'change to your sheet name.
Dim lstrow As Long
lstrow = .Cells(.Rows.Count, 2).End(xlUp).Row
Dim i As Long
For i = lstrow To 2 Step -1
Rows(i + 1 & ":" & i + 3).Insert
.Cells(i + 1, 4).Resize(3).Value = Application.Transpose(textArr)
Next i
End With
End Sub
Try this:
Sub forloop()
Dim i As Long
vLastRow = Cells.Find(What:="*", After:=Cells(1, 1), searchorder:=xlByRows, SearchDirection:=xlPrevious).Row
For i = vLastRow To 2 Step -1
If Cells(i, "B") <> "" Then
Rows(i + 1 & ":" & i + 3).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range(Cells(i + 1, "B"), Cells(i + 3, "B")) = "your Text"
End If
Next
End Sub

Sum columns in a new column next to the selection

I'm trying to sum a number of columns together in a new column.
I have been able to get to the point where I take A+B and place the values in C. However, the actual columns I will need to sum vary. Is there a way I can edit my code so that any selected columns can be summed in a new column to the right of the selection?
For example. If I select columns B-D, it would insert a new column in E that houses the sums of columns B,C, and D. Or if I selected E-F, it would insert a new column in G that houses the sums of columns E and F.
Sub SumColumns()
Lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).row
For i = 1 To Lastrow
Range("C" & i).Value = Range("A" & i).Value + Range("B" & i).Value
Next i
End Sub
Here is my (rather sloppy) solution:
Sub Test()
Dim col1 As String, col2 As String, lastrow As Long
col1 = Split(Selection.Address, "$")(1)
col2 = Split(Selection.Address, "$")(3)
lastrow = Cells(Rows.Count, col2).End(xlUp).Row
Columns(col2 & ":" & col2).Offset(0, 1).Insert Shift:=xlToRight
For i = 1 To lastrow
Range(col2 & i).Offset(0, 1).Value = WorksheetFunction.Sum(Range(col1 & i & ":" & col2 & i))
Next i
End Sub
I say this is sloppy, because if you have the entire column selected, you won't Split out the column values appropriately. So it depends on how you're trying to do this.
This procedure will let you select any range. It will add a column at the end of the range and sum each row to the new column.
Sub test()
Call InsertSumCol(Sheet1.Range("B2:E4"))
Call InsertSumCol(Sheet2.Range("E1:F3"))
End Sub
Private Sub InsertSumCol(ByVal oRange As Range)
'Add Sum Column to end of Range
oRange.Worksheet.Columns(oRange.Column + oRange.Columns.Count).Insert shift:=xlToRight
' Sum Each Row in Range
Dim oRow As Range
For Each oRow In oRange.Rows
oRow.Cells(1, oRow.Columns.Count + 1) = WorksheetFunction.Sum(oRow)
Next
End Sub
I assume that you want to sum vertically all cells in a row starting from column A.
Try this (some tips and comments are in code):
'use this in order to avoid errors
Option Explicit
Sub SumColumns()
'always declare variables!
Dim LastRow As Long, i As Long, ws As Worksheet, lastCol As Long, firstCol As Long
'if you can, avoid using ActiveSheet, Selection, etc. it's prone to errors
Set ws = ActiveSheet
i = 1
Do
firstCol = ws.Cells(i, 1).End(xlToRight).Column
lastCol = ws.Cells(i, ws.Columns.Count).End(xlToLeft).Column
'there isn't any filled cells in a row
If lastCol = 1 Then Exit Do
ws.Cells(i, lastCol + 1).Value = Application.WorksheetFunction.Sum(ws.Range(ws.Cells(i, firstCol), ws.Cells(i, lastCol)))
i = i + 1
Loop While True
End Sub
Before and after:

Delete Blank Rows from Column B

I am trying delete all rows where column B to AD (Lastrow) are blank. On my excel sheet every couple of rows or so column B to AD are blank so i am trying to delete those rows. I have been trying to use the below code:
Sub T()
Dim rng As Range
Set rng = Range("B1:AC10402")
rng.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
No success
Try this code:
Sub DeleteBlankRows()
Dim i As Long
Dim lastRow As Long: lastRow = 10 'here you have to specify last row your table uses
For i = lastRow To 1 Step -1
If Cells(i, Columns.Count).End(xlToLeft).Column = 1 Then
Rows(i).Delete
End If
Next i
End Sub
Little explanation
You specified that you need check for emptiness within row, columns B through AD. This piece of code Cells(i, Columns.Count).End(xlToLeft).Column will return column of the right-most (starting from first column), non-empty cell. If whole row is empty or there's data in first column - it will return 1 - which is misleading, when you are considering A cloumn. But it isn't here, since we consider columns starting with B. So if it returns 1, it means that the row is empty and should be deleted.
this deletes all blank rows in column B
Dim LastRow, i As Integer
LastRow = activesheet.Cells(activesheet.Rows.Count, "A").End(xlUp).Row
For i = LastRow To 1 Step -1
If WorksheetFunction.CountA(Range("B" & i)) = 0 Then
Range("B" & i).EntireRow.Delete
End If
Next i
this deletes all blank rows if column B to column AC is blank
Dim LastRow, i As Integer
LastRow = activesheet.Cells(activesheet.Rows.Count, "A").End(xlUp).Row
For i = LastRow To 1 Step -1
If WorksheetFunction.CountA(Range("B" & i & ":" & "AC" & i)) = 0 Then
Range("B" & i & ":" & "AC" & i).EntireRow.Delete
End If
Next i

Integer not storing correct LastRow value after many loops: VBA Run-Time error

In the code below, my LastRow variable is not storing the right row number on the 27th loop (i = 27) causing the code to malfunction
I have used the F8 step through multiple times and noticed that the issue is on the 27th loop. The LastRow variable is meant to be +1204 rows from the previous LastRow value on each iteration of the loop, so I was expecting LastRow = 32509 instead of LastRow = 31316. For reference, on the 26th loop, LastRow = 31305. I'm not sure why the it is finding the wrong LastRow when the code has worked for the first 26 loops.
I am trying to get from my Source Table to my Desired Table:
Source Table
to
Desired Table
Also , the final error that shows is:
Run-Time error '1004': Application -defined or object- defined error
Sub Populate_entity()
Dim i As Integer
i = 1
Dim LastRow As Long
Dim SearchText As String
Do While i < 122 ' go across entity (columns wise)
If i = 1 Then
Range("E1").Select
Selection.Copy
SearchText = ActiveCell.Value
ActiveCell.End(xlToLeft).Select 'snap to left (cell A1)
ActiveCell.Offset(0, 2).Select 'move to cell C1
ActiveCell.Offset(1, 0).Select ' move to cell C2
Else
ActiveCell.Offset(0, i + 1).Select
Selection.Copy
SearchText = ActiveCell.Value
ActiveCell.End(xlToLeft).Select
ActiveCell.Offset(0, 2).Select
ActiveCell.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
End If
ActiveSheet.Paste
ActiveCell.Offset(1203, 0).Select
ActiveSheet.Paste
ActiveCell.End(xlUp).Select
' ======== Error here ========
LastRow = Cells.Find(What:=SearchText, After:=ActiveCell, LookIn:=xlValues, SearchOrder:=xlByRows).Row
Range("C" & ActiveCell.Row & ":C" & LastRow).FillDown
ActiveCell.End(xlUp).Select
i = i + 1
Loop
End Sub
A summary of what you want, as you described in the comments:
Copy the values from cells E1:DU1, paste each cell 1204 times in column C.
1st loop it will paste cell E1 in C2:C1205
2nd loop it will paste cell F1 to C1206:C2409
etc.
This code achieves that:
Sub Populate_entity()
' Declare 2 range variables (top row to copy from and paste destination)
Dim RowRange As Range
Dim PasteCells As Range
' Use the With block to specify the sheet. If you want the destination
' to be another sheet, then you can specify that instead:
' ThisWorkbook.Sheets("SheetName").Range("...")
With ThisWorkbook.ActiveSheet
Set RowRange = .Range("E1:DU1") ' Set range to copy from
Set PasteCells = .Range("C2:C1205") ' Set paste cells, blocks of 1204 cells in column C
End With
' Loop through RowRange, copy each cell's value into PasteCells
' Then offset the PasteCells range by 1024 rows, so next RowRange cell
' is inserted underneath previously copied cells.
Dim ofst As Long
For ofst = 1 To RowRange.Cells.Count
' Use .Value to avoid the (comparably slow) copy/paste operation
PasteCells.Offset((ofst - 1) * 1204, 0).Value = RowRange.Cells(ofst).Value
Next ofst
End Sub
In my opinion you don't need any search because your code always places the SearchString in row 1205. Since you know that it is there you don't need to look for it. This thought brings me to the code below.
Sub Populate_Entity()
Dim C As Long ' Column
Dim Target As Range
Dim FirstRow As Long
Dim LastRow As Long
FirstRow = 2
LastRow = 7 '1205
C = 3
Range("C2").value = Range("E1").value
' Cells(2, C).Value = Cells(1, 5).Value
Do
Set Target = Range(Cells(FirstRow, C), Cells(LastRow, C))
Target.FillDown
C = C + 1
Cells(2, C).value = "Can't figure"
Loop While C < 3 ' 122
End Sub
I have cut the loop short to only 7 rows (instead of 1205) and 3 columns (instead of 122). I just couldn't figure out where the text in the FirstRow should come from. For column C it comes from E1, but where does it come from in the subsequent columns? You can fill this in using the method I showed you above, like, Cells(2, C).Value = Cells(1, 5).Value. I believe that the 5 can be replaced by a value derived from the current C, perhaps C + 2.
Note the Cells(2, C).Value doesn't refer to the value in cell C2. Instead if refers to the cell in Row 2, Column C.

Excel: Transposing large column with ~45,000 cells to rows with from 1-8 ID-tied

First post here so bear with me. It's possible something similar to what I am going to ask has been posted but my technical illiteracy might have prevented me from finding it.
I have a column of data ~45,000 cells.
Within these cells lie descending data of individuals identified by an ID#, followed by anywhere from 1-8 additional cells with criteria relevant to the preceding ID#.
What I'm trying to do it convert this large column to a row for each of the ~5,500 IDs.
Here is an example of what I'm trying to achieve
I come from a beginner level SAS background and have only used Excel previously in a very brief manner, and have been trying to figure this out off and on for a week or two now. I've started transposing them manually but that is going to take forever and I hope there's an easier way.
My best guess would be, from what I've seen so far, that a VBA code could be written, but I don't know where to start with that. I'm also open to any other ideas on how to achieve the result I'm trying to get.
Thanks in advance!
Sub TransposeData()
Dim Data, TData
Dim x As Long, x1 As Long, y As Long
With Worksheets("Sheet1")
Data = .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
End With
ReDim TData(1 To UBound(Data, 1), 1 To 8)
For x = 1 To UBound(Data, 1)
'If the Data macthes the ID pattern (7 Digits) then
'increment the TData Row Counter
If Data(x, 1) Like "#######" Then
x1 = x1 + 1
y = 0
End If
'Increment the TData Column Counter
y = y + 1
TData(x1, y) = Data(x, 1)
Next
With Worksheets("Sheet2")
With .Range("A" & .Rows.Count).End(xlUp)
If .Value = "" Then 'If there is no data, start on row 1
.Resize(x1, 8).Value = TData 'Resize the range to fit the used elements in TData
Else ' Start on the next empty row
.Offset(1).Resize(x1, 8).Value = TData
End If
End With
End With
End Sub
If I correctly understand your problem the following code should solve it;
Sub ColToRow()
Dim inCol As Range
Set inCol = Application.InputBox(Prompt:="Please Select Range", Title:="Range Select", Type:=8) 'Get the input column as a range
Dim outCol As Range
Set outCol = inCol.Offset(0, 2) 'Set the output column as a range
Dim index As Long 'Current row
Dim cell As Range 'Current cell
Dim lastRow As Long 'The last row
Dim currRow As Long 'Current output row
Dim currCol As Long 'Current output column
lastRow = inCol.SpecialCells(xlCellTypeLastCell).Row
currRow = inCol.Row - 1
currCol = 0
For index = inCol.Row To lastRow
Set cell = ActiveSheet.Cells(index, inCol.Column) 'Set the cell range to the current cell
If Application.WorksheetFunction.IsNumber(cell) And Len(cell.Value) = 7 Then 'If numeric then we assume it is the ID, else we assume it is the
currRow = currRow + 1 'Advance to next output row
currCol = 0 'Reset column offset
cell.Copy Destination:=ActiveSheet.Cells(currRow, outCol.Column + currCol) 'Copy ID
ElseIf currRow > 0 Then 'Ensure we are within the row bounds and not at 0 or below
currCol = currCol + 1 'Advance the column
cell.Copy Destination:=ActiveSheet.Cells(currRow, outCol.Column + currCol) 'Copy Text Values until we get the next numeric value
End If
Next index 'Advance the row
End Sub
The code simply goes (in order) down the column and does the following;
- If the cell has a numeric value then we assume it is the ID and create a new row.
- If the cell has a text value we just add it to the next column in the current row, it'll continue to do this with however many string values until a new ID is reached.
Hope it helps.
-Regards
Mark
Another possible solution, based on ID being 7 digits numbers and all other numbers being not
Option Explicit
Sub main()
Dim area As Range
Dim iArea As Long
With ThisWorkbook.Worksheets("Transpose") '<--| reference relevant worksheet (change "Transpose" to your actual sheet name)
With .Range("A1", .Cells(.Rows.COUNT, 1).End(xlUp).Offset(1))
.Cells(.Rows.COUNT, 1).Value = 1111111 '<--| add a "dummy" ID to end data
.AutoFilter Field:=1, Criteria1:=">=1000000", Operator:=xlAnd, Criteria2:="<=9999999" '<--| filter its "JobCol_Master" named range on textbox ID
.Cells(.Rows.COUNT, 1).ClearContents '<--| remove "dummy" ID
With .SpecialCells(xlCellTypeVisible)
.Parent.AutoFilterMode = False
For iArea = 1 To .Areas.COUNT - 1
Set area = .Parent.Range(.Areas(iArea), .Areas(iArea + 1).Offset(-1))
.Parent.Cells(.Parent.Cells.Rows.COUNT, 3).End(xlUp).Offset(1).Resize(, area.Rows.COUNT).Value = Application.Transpose(area.Value)
Next iArea
End With
End With
End With
End Sub