I would like to enter 3 blank rows whenever the value in column A changes. I found the following vba code online. Is it possible to adapt this to get it to enter 3 instead of 1 row? I also would like to get rid of the input box. My knowledge of vba is very limited so I apologize for that.
I just need some way to enter 3 blank rows whenever the value in the ID column changes without any sort of input box or other dialogue box. Any help would be much appreciated!
Dim curR As Range
Set curR = Application.Selection
Set curR = Application.InputBox("Select the Range of Cells to be insert blank rows", xTitleId, curR.Address, Type:=8)
For i = curR.Rows.Count To 2 Step -1
If curR.Cells(i, 1).Value <> curR.Cells(i - 1, 1).Value Then
curR.Cells(i, 1).EntireRow.Insert
End If
Next
End Sub
picture
The procedure below will allow you to specify how many rows you want to insert after each change. You can also specify another ID column, simply by changing the value of the constant TargetClm.
Sub Insert3Rows()
' 298
Const TargetClm As String = "A" ' change to suit
Const NumRows As Integer = 3 ' number of rows to insert
Dim R As Long ' loop counter: sheet rows
Application.ScreenUpdating = False
With Worksheets("Sheet1") ' change to suit
' loop from next to last used cell to row 2
For R = (.Cells(.Rows.Count, TargetClm).End(xlUp).Row - 1) To 2 Step -1
If .Cells(R, TargetClm).Value <> .Cells(R + 1, TargetClm).Value Then
.Cells(R + 1, TargetClm).Resize(NumRows).EntireRow.Insert
End If
Next R
End With
Application.ScreenUpdating = True
End Sub
No provision has been made to handle blank rows. Therefore, please don't run the code twice on the same worksheet.
Related
I am trying to create a vba code for excel that hides a column if cells are empty for 10 progressive cells before moving to the next column, starting with cell m9. However, I am having trouble solving this error message. I am new to VBA, so I'm unsure how to proceed. Any help would much be appreciated. Thank you.
Sub HideColumns()
' Assumed if empty cell for 10 progressive cells in the same column, then is empty
' for the entirety of the test
' Our tests start at cell M9, so we will use a conditional loop to use the offset
' method on the range object from there
StartCell = ActiveSheet.Range("M9").Select
For i = 1 To 10
If IsEmpty(ActiveCell.Value) = True Then
Range(ActiveCell).Offset(i).Select
ElseIf IsEmpty(ActiveCell.Value) = False Then
Exit For
End If
Next i
If i = 10 Then
HiddenColoumn = ActiveCell.Column
Columns("HiddenColoumn:HiddenColoumn").Select
Selection.EntireColumn.Hidden = True ' now the column is hidden as there is no data for 10 progressive cells
Range(ActiveCell).Offset(-10, 1).Select
i = 1 ' reset counter for next loop
ElseIf i <> 10 Then
Range(ActiveCell).Offset(-10, 1).Select
i = 1 ' reset counter for next loop
End If
First: Don't select anything. You can address any cell or range just by specifying its address.
Second: The task isn't to check if the first 10 cells are blank but whether there are 10 consecutive blank cells in the column. What about if M9:M10 and M16 have values but all other cells are blank? Then it would be important to know how many rows there are in the sheet because by looking at only one column you can't know if the 10 cells are blank (within the sheet) or not blank (below the sheet).
So, you arrive at a different coding strategy.
Sub HideColumns()
' 257
' Assumed if empty cell for 10 progressive cells in the same column, then is empty
' for the entirety of the test
Dim Blank As Integer ' count blank cells
Dim Cl As Long ' last used column in the sheet
Dim Rl As Long ' last used row in the sheet
Dim C As Long ' loop counter: columns
Dim R As Long ' loop counter: rows
With Worksheets("Sheet1") ' better (meaning safer!) than 'ActiveSheet'
With .UsedRange
Cl = .Columns.Count + .Column - 1
Rl = .Rows.Count + .Row - 1
End With
' Our tests start at cell M9,
For C = .Columns("M").Column To Cl
Blank = 0
For R = 9 To Rl
If .Cells(R, C).Value = "" Then
Blank = Blank + 1
If Blank > 9 Then Exit For
Else
Blank = 0
End If
Next R
.Columns(C).Hidden = (Blank = 10)
Next C
End With
End Sub
So I have been working on this little piece of code for a couple of days now and have hit a snag that I just cannot figure out. Basically I have a nested for loop that is supposed to take values from one Sheet and put them in a data sheet so that those value can be saved and averaged out over time.
I want the data from the cells M5 - M35 to get put into the data sheet like this: from left to right A3 - AC200, but I also want the loop to stop once the M5 - M35 range runs out of values and when the user next pushes the button to store data I want the loop to start on the next line down.
So This Spreadsheet is for my work, it is for a Butchery Yield Test and I want it to have it's owned database stored on a hidden sheet that will be averaged out over time so I or others can come back to it and update it every few months to make the averages more accurate and to get a better understanding of the profitability of certain cuts of meat.
I have tried setting the loop values back to their starting values once the loop has filled out all the data which worked and I thought I'd solved the issue until I ran the test multiple time and found that the first and second time work as expected from the third onwards however it doesn't start the loop down at the next row it just continues through the range
Sub subData1()
Dim rng As Range
Dim rcell As Range
Dim ws As Worksheet
Dim Tws As Worksheet
Set Tws = Worksheets("Test")
Set ws = Worksheets("data")
For i = 3 To 200 'range is from cell A3 - A200
'if start cell already has value go down a row
If ws.Cells(i, 1).Value <> "" Then
i = i + 1
End If
'set the range for data sheet
Set rng = ws.Range(ws.Cells(i, 1), ws.Cells(i, 30).End(xlToRight))
For f = 5 To 35
For Each rcell In rng 'loop through each cell in data sheet range
If rcell.Value = "" Then 'if cell is blank input data
If Tws.Cells(f, 13).Value <> "" Then
'Check the selected Cell has a value
rcell.Value = Tws.Cells(f, 13).Value
f = f + 1
End If
Else
If f > 5 Then
MsgBox "Data Storage Updated", , "Data Storage"
f = 5
Exit Sub
'Else
'MsgBox "Value Must Be Greater Than Zero", , f
'f = 5
'Exit Sub
End If
End If
Next
Next
Next
End Sub
The reason it's working the first and second time is because of this line
If ws.Cells(i, 1).Value <> "" Then
i = i + 1
End If
But, if you'll notice, it's only running once for each iteration. Which means that on a blank sheet, it will evaluate false on the first iteration of the first run and continue, on the first iteration of the second run, it will evaluate true and move down one row to row 4, but on the first iteration of the third run it will also evaluate true and move down to row 4 and then place data starting at ws.Range(ws.Cells(i, 1), ws.Cells(i, 30).End(xlToRight))
You need to change your If-End If to a function that will retrieve the last used row in Column A of your data sheet. Additionally, you probably don't need your outer For-Next loop since that's looping through your output sheet and would output the same M5:M35 values for every single row.
If I understand your needs correctly, I believe you could utilize this to accomplish what you're looking for
Dim rng As Range
Dim ws As Worksheet
Dim Tws As Worksheet
Dim endRow As Long
Set Tws = Worksheets("Test")
Set ws = Worksheets("data")
endRow = ws.Range("A" & Rows.Count).End(xlUp).Row + 1
Set rng = ws.Cells(endRow, 1)
For f = 5 To 35
If Tws.Cells(f, 13).Value <> "" Then
rng.Value = Tws.Cells(f, 13).Value
Set rng = rng.Offset(0, 1)
End If
Next
With this, every sequential button click would insert data at a new row, looping through Tws.Cells(f,13) and placing that value in the right-most column by incrementally setting the range.
I would like to ask your help for this task.
The excel sheet contains duplicated items in ColumnA. I want to combine these duplicates into one row. Please see the picture.
As the actual picture shows, there are three As in ColumnA. For every A there are some cells from ColumnB. Lets say those are the values to A. The values from every rows are marked with different colors seperately.
I want to combine A's values into one row, as the target picture shows.
The excel sheet was pre-sorted, so that all duplicates from ColumnA always appear together.
Please be noticed there are also items without duplicates: There is only one E in ColumnA. No transpose is required for this row.
Please also be noticed that there could be more duplicted items in ColumnA. E.g. 10x Ts, or 30x Ks.
To make the task easier, it is no need to delete the blank rows after the transformation.
The colors are used only to show the problem, there is no color in the excel sheet.
So far for this task.
Actually I asked a similar question before: Excel VBA: How to transform this kind of cells?
In the link there are some very good codes, but sadly I am not capable to rewrite the code for this task.
So please help me~
But please dont forget to have a happy weekend~
Thanks!
Try the code below ("bonus" feature, also removes the empty rows).
As you wrote in your post, the data is sorted according to Column A, and there are no empty rows in your data.
Sub TransposeDup()
Dim LastCol, LastColCpy As Long
Dim lrow As Long
lrow = 1
While Cells(lrow, 1) <> ""
If Cells(lrow, 1) = Cells(lrow + 1, 1) Then
LastCol = Cells(lrow, Columns.Count).End(xlToLeft).Column
LastColCpy = Cells(lrow + 1, Columns.Count).End(xlToLeft).Column
Range(Cells(lrow + 1, 2), Cells(lrow + 1, LastColCpy)).Copy Destination:=Cells(lrow, LastCol + 1)
Rows(lrow + 1).EntireRow.Delete
Else
lrow = lrow + 1
End If
Wend
End Sub
Something like the following should get you in the right direction. This doesn't copy formats, but it gets the values. You could tweak it to get where you need to go though:
Sub dedup_and_concat()
Dim intWriteCol As Integer
Dim intReadCol As Integer
Dim intWriteRow As Integer
Dim intReadRow As Integer
Dim intStartRow As Integer
Dim intEndRow As Integer
Dim strPrevRowValue As String
'Start and end rows:
intStartRow = 1
intEndRow = 8
'initial values:
intWriteRow = 1
'Loop from your start row to your end row
For intReadRow = intStartRow To intEndRow 'beginning and ending rows
intReadCol = 2
'If we are at the first row, then just capture values
'Also if this is a new value, then reset all of the write variables
If intReadRow = intStartRow Or Sheet1.Cells(intReadRow, 1).Value <> Sheet1.Cells(intWriteRow, 1).Value Then
'set the row and initial column we are writing to
intWriteRow = intReadRow
intWriteCol = Sheet1.Cells(intReadRow, 1).End(xlToRight).Column() + 1
Else
'We are on a row that needs to be concatenated and deleted
'So loop through all of the columns to get their values
'And write their values to the read row and read col
Do Until Sheet1.Cells(intReadRow, intReadCol).Value = ""
Sheet1.Cells(intWriteRow, intWriteCol).Value = Sheet1.Cells(intReadRow, intReadCol).Value
'increment read and write columns
intWriteCol = intWriteCol + 1
intReadCol = intReadCol + 1
Loop
'remove this rows values
Sheet1.Rows(intReadRow).ClearContents
End If
Next intReadRow
End Sub
I want to delete the entire rows for cell that contain 'Total' and 'Nett' in column C.
I have tried the macro recording using Auto Filter but it only delete rows up to a specified range (which may differ if I use other set of data).
Appreciate your help!
Here you go. Just copy and paste this sub into your file. To use it, select the SINGLE column that you want to evaluate. This will go through every cell that has been selected, and if it matches the criteria, it will delete the entire row. Let me know if you have any questions. Good luck!
Sub DeleteRows()
'Enter the text you want to use for your criteria
Const DELETE_CRITERIA = "Test"
Dim myCell As Range
Dim numRows As Long, Counter As Long, r As Long
'Make sure that we've only selected a single column
If Selection.Columns.Count > 1 Then
MsgBox ("This only works for a single row or a single column. Try again.")
Exit Sub
End If
numRows = Selection.Rows.Count - 1
ReDim arrCells(0 To 1, 0 To numRows) As Variant
'Store data in array for ease of knowing what to delete
Counter = 0
For Each myCell In Selection
arrCells(0, Counter) = myCell
arrCells(1, Counter) = myCell.Row
Counter = Counter + 1
Next myCell
'Loop backwards through array and delete row as you go
For r = numRows To 0 Step -1
If InStr(1, UCase(arrCells(0, r)), UCase(DELETE_CRITERIA)) > 0 Then
Rows(arrCells(1, r)).EntireRow.Delete
End If
Next r
End Sub
This will loop through cells in Column C and delete the entire row if the cell contains either "Total" or "Nett". Keep in mind that it is case sensitive, so the first letter of "Nett" or "Total" would need to be capitalized for this to find it. There can be other text in the cell however. Also note that the references are not fully qualified (ie Workbook().Worksheet().Range()) because you did not provide a workbook or worksheet name. Let me know if this does not work for you.
Sub Delete()
Dim i as Integer
For i = Range("c" & Rows.Count).End(xlUp).Row To 1 Step -1
If Instr(1, Cells(i, 3), "Total") <> 0 Or Instr(1, Cells(i,3),"Nett") <> 0 Then
Cells(i,3).EntireRow.Delete
End If
Next i
End Sub
Hello and first let me say thank you!
I use Excel to capture user requirements and descriptions. I then take that information and clean it up and paste into presentation docs, apply formatting, paste into Powerpoint, etc. It can be 100s of lines in total that this is done for. What I'm looking for is a macro that I can apply to data once it is pasted into Excel. The data will be text, non-numeric
I have a macro that I use to insert a blank row as every other row. I then do everything else manually (macro shown below).
What I'm looking for is a macro that inserts a blank row, then offsets Column 2 by 1 row down. then pastes column 1 into column 2(without copying the blank cells over my already existing data in column 2).
I've pasted a link to an image of what I'm looking for. I've also tried to show below (numbers are column 1, letters are column 2).
2 columns to 1 column - desired result
1 A 2 B3 C
Result I want:
1
A
2
B
3
C
My current "Blank Row" Macro:
Sub insertrow()
' insertrow Macro
Application.ScreenUpdating = True
Dim count As Integer
Dim X As Integer
For count = 1 To 300
If ActiveCell.Value <> "" Then
ActiveCell.Offset(1, 0).Select
Range(ActiveCell, ActiveCell.Offset(0, 0)).EntireRow.Insert
ActiveCell.Offset(1, 0).Select
For X = 1 To 1
Next X
Else
ActiveCell.Offset(1, 0).Range("a1").Select
End If
Next count
End Sub
This should work, but you'll have to adjust a little for your exact layout and needs.
Sub mergeColumns()
Dim mergedData As Variant
ReDim mergedData(1 To 600)
dataToProcess = Range("A2:B301")
For i = 1 To 300
mergedData(i * 2 - 1) = dataToProcess(i, 1)
mergedData(i * 2) = dataToProcess(i, 2)
Next i
Range("B2:B601") = WorksheetFunction.Transpose(mergedData)
End Sub
The following does what you need without inserting blank rows. It also calculates what the last row is on the sheet that has 2 columns so that you don't need to hard-code when the loop will end.
The comments should help you understand what is happening each step of the way. You can then modify this to work with your particular workbook. There are a lot of ways you could go about this. I chose to put the pivoted result on a second sheet.
Sub PivotTwoColumnsIntoOne()
Dim wb As Workbook
Dim src As Worksheet
Dim tgt As Worksheet
Dim rng As Range
Dim cell As Range
Dim lastRow As Long
Dim targetRow As Long
Set wb = ThisWorkbook
' set our source worksheet
Set src = wb.Sheets("Sheet1")
' set our target sheet (where the single column will be)
Set tgt = wb.Sheets("Sheet2")
' get the last row on our target sheet
lastRow = src.Range("A" & src.Rows.Count).End(xlUp).Row
' set the starting point for our target sheet
targetRow = 1
Set rng = src.Range("A1:A" & lastRow)
For Each cell In rng
With tgt.Range("A" & targetRow)
' get the value from the first column
.Value = cell.Value
' get the value from the second column
.Offset(1).Value = cell.Offset(, 1).Value
.HorizontalAlignment = xlLeft
End With
targetRow = targetRow + 2
Next cell
End Sub