I have a worksheet named "subtotal" where I am identifying 2 line to be subtracted with 1 & 2 (line with "2" should be subtracted from line with "1"). I need to insert a row below the line with "2" in order to add the correct formula in the required cells.
I am selecting the column containing the criteria (1,2), then executing a find comand for the "2", I then use the offset property to select the cell below and insert a row. This works great, however when I apply the loop it will not stop. I have indicated that if the active cell = "2XXXXX" then exit Do. I have tried several variations and end up with the same endless loop. Can anyone tell me what i am doing wrong?
Here is my code:
Sub insert_row_1()
'
Range("D1").Select
Selection.End(xlDown).Activate
ActiveCell.Offset(1, 0).Activate
ActiveCell.FormulaR1C1 = "2XXXXX"
Range("A1").Select
Columns("D:D").Select
Selection.Find(What:="2", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
Do
If ActiveCell.Value = "2" Then
ActiveCell.Offset(1, 0).Activate
ActiveCell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ElseIf ActiveCell.Value <> "2" Then
With Columns("D")
Selection.FindNext(After:=ActiveCell).Activate
ActiveCell.Offset(1, 0).Activate
ActiveCell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
ElseIf ActiveCell.Value = "2XXXXX" Then
Exit Do
End If
Loop
End Sub
Unfortunately, I was not able to get your loop to work, but, if I understand your goal correctly, there may be an easier way to accomplish what you need.
As I understand it, you want to:
Insert a row below every row that has a 2 in Column D
In column E of the new row, subtract the value of Column E one row above the new row from the value in column E one row above that.
The below will accomplish that:
Sub InsertAfter2()
For Each Cell In Range("D:D")
If Cell.Row <> 1 Then
If (Cells(Cell.Row - 1, 4).Value = 2) Then
Cell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Cells(Cell.Row - 1, 4).Value = "Result:"
Cells(Cell.Row - 1, 5).Value = (Cells(Cell.Row - 3, 5).Value) - (Cells(Cell.Row - 2, 5).Value)
End If
End If
Next Cell
End Sub
This will take data that looks like:
And produce data that looks like:
Related
I have recorded a macro that lets me split a persons monthly schedule into weeks.
Sub HoursSplit()
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveCell.Offset(0, 1).Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[-1]/4"
ActiveCell.Offset(0, 1).Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[-1]"
ActiveCell.Offset(0, 1).Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[-1]"
ActiveCell.Offset(0, -3).Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[1]"
End Sub
As an example:
Person
Month 2
Month 3
Person 1
173
173
Effectively:
I select the monthly hours im looking to split (i.e Month 2)
copy it
select a cell elsewhere with no data in it
Hit Cntrl + Shift + C
In the case above, it gives me
Cell 1
Cell 2
Cell 3
Cell 4
43.25
43.25
43.25
43.25
Thing is, this only works for a single person/cell, making splitting everyones hourshours up into weeks tedious.
How can i modify the above to work for an entire column range selection (i.e Multiple people at once for the same month)?
Another way you can do what you want (and should be faster).
Public Sub HoursSplit_Test()
Dim cell As Range
For Each cell In Selection
cell.Resize(, 4).Value = cell.Value / 4
Next cell
End Sub
Was able to solve my own issue eventually.
Public Sub HoursSplit_Test()
Dim cell As Excel.Range
For Each cell In Selection
cell.Value = cell.Value / 4
cell.Copy
cell.Offset(0, 1).PasteSpecial
cell.Offset(0, 2).PasteSpecial
cell.Offset(0, 3).PasteSpecial
Next cell
End Sub
I have certain values in my column A.
For exapmple:
Header
A
A
C
C
D
D
E
F
I want to keep rows having D and remove all other. As a first step, Have sorted my sheet.
Now trying below code but its giving error of
Invalid or unqualified reference
Dim strA As Range
Dim strB As Range
Range("A:A").Select
Selection.Find(What:="D", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Offset(-1, 0).Select
Set strA = .ActiveCell
Range(Selection, Selection.End(xlUp)).Select
Range(Selection, ActiveCell.Offset(1, 0).Select).Select
ActiveCell.Offset(1, 0).Select
Set strB = .ActiveCell
Range(strA, strB).Select
End Sub
Maybe something like this :
Sub test()
n = Application.WorksheetFunction.CountIf(Range("A:A"), "D")
Set c = Range("A:A").Find("D", lookat:=xlWhole)
Range("A" & c.Row, Range("E" & c.Row).Offset(n - 1, 0)).Copy Destination:=Range("A2") 'change E as needed, depends how many column is your data
Set rngDel = Range("A1").Offset(n + 1, 0)
Range(rngDel, rngDel.End(xlDown)).EntireRow.Delete
End Sub
Before running the code, the data table must be sort first by column A.
The code will count how many "D" are there in column A.
Then it get the cell where it find the first "D"
From there it copy all the cells which has "D" value
then paste it to cell A2
lastly, it delete the remaining cells which doesn't have "D" value
I'm trying to write code which automates something: I've got a table of data which I need to add a column into, then put a sum in which goes all the way down to the bottom row of data and no further. I know how to define the bottom row as a variable; but what if the column I'm entering the data can vary too? In my example, the column I want to do the sums in is always to the left of the column entitled '16'. It will always start at row 2, but it won't always be column O. It might be column P, or Q, for example.
Sub enter_column_and_add_calculations()
Dim NBottomrow
Call find_bottom_row
NBottomrow = ActiveCell.Row
'find column entitled '16':
Range("A1").Select
Cells.Find(What:="16", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext,
MatchCase:=False _
, SearchFormat:=False).Activate
'insert new column to the left:
Selection.EntireColumn.Insert , CopyOrigin:=xlFormatFromLeftOrAbove
'insert text in the cell:
ActiveCell.FormulaR1C1 = "OOT Debt"
'offset one cell below:
ActiveCell.Offset(1, 0).Range("A1").Select
'i'm now in the cell i want my range to start at. In this example it's cell O2, but it often varies:
ActiveCell.FormulaR1C1 = "=SUM(RC[1]:RC[5])"
Selection.AutoFill Destination:=Range("O2:O" & NBottomrow)
End Sub
Private Sub find_bottom_row()
Range("A1").Select
Selection.End(xlDown).Select
End Sub
Many thanks for your help :-)
Try,
Sub enter_column_and_add_calculations()
dim m as variant, lr as long
with worksheets("sheet1")
m = application.match(16, .rows(1), 0)
if iserror(m) then exit sub
lr = .cells(.rows.count, m).end(xlup).row
.cells(lr+1, m).formula = "=sum(" & .range(.cells(2, m), .cells(lr, m)).address(0,0) & ")"
end with
end sub
I have read just about every other question on here on merging rows and consolidating data. I did come across a solution I think will work for me, but when I ran the macro it didn't actually sum the right column. Being new to VBA, I'm having trouble figuring out what needs to change in the macro to work in my sheet.
Background:
I want to use a macro because I get a report every day that I have to manipulate so that it can process into our system. I have created a VBA macro to do the manipulation for me, but I have realized that the report now has duplicate lines with different values. Below is an example with the last set of numbers needing to be added together. (Column J on my actual report)
i.e.
Row 1: C3=1234, Name, C5=ABC, C5Name, C4=DEF, C4Name, 21361
Row 2: C3=1234, Name, C5=ABC, C5Name, C4=DEF, C4Name, 132165
This is the solution I found, but I need to know what to change to correspond with the column I actually need summed up.
Sub Merge()
Dim ColumnsCount As Integer
Dim i As Integer
Range("A1").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Do While ActiveCell.Row <= ActiveSheet.UsedRange.Rows.Count
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
For i = 1 To ColumnsCount - 1
ActiveCell.Offset(0, i).Value = ActiveCell.Offset(0, i).Value + ActiveCell.Offset(1, i).Value
Next
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
Any and all help is greatly appreciated. Please let me know if I need to provide additional information.
~Andrea
It would have been better to see your table. You still have not explained enough. This answer is not so different from user1016274's answer. The code above first order by the columns B, D and H then checks and deletes the duplicates by the time adding up their J column values, by comparing same columns.
Sub Merge()
Range("A1").Sort Key1:=Range("B1"), Order1:=xlAscending, Key2:=Range("D1"), Order2:=xlAscending, _
Key3:=Range("H1"), Order3:=xlAscending, Header:=xlYes
'I assume there are column headers. If not, use "Header:=xlNo" instead of "Header:=xlYes"
Range("A2").Select 'I assume there are column headers. If not, use "Range("A1").Select" instead of "Range("A2").Select"
Do While ActiveCell.Row <= ActiveSheet.UsedRange.Rows.Count
If ActiveCell.Offset(0, 1).Value = ActiveCell.Offset(1, 1).Value And ActiveCell.Offset(0, 3).Value = ActiveCell.Offset(1, 3).Value And ActiveCell.Offset(0, 7).Value = ActiveCell.Offset(1, 7).Value Then
ActiveCell.Offset(0, 9).Value = ActiveCell.Offset(0, 9).Value + ActiveCell.Offset(1, 9).Value
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
You don't have to loop through all columns just to add column J's values:
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
ActiveCell.Offset(0, 10).Value = ActiveCell.Offset(0, 10).Value + ActiveCell.Offset(1, 10).Value
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
BTW, are you sure you want to increment the active cell's row only if the row is not duplicated? Might be that it works because of the DeleteRow operation but I just wanted to ask.
edit: deleted orphaned Next statement, sorry.
Looking for help on a macro to take chunks of data on further rows, and place them into columns instead.
I've attached a picture to depict this. All of the chunks of data will split determined by the first column, 1 or 2 in the picture. I simply want to move chunk two up and next to 1. The only problem I've run into is that for each chunk, the number of columns is variable.
Edit: Image link incase the embedded isn't showing up: enter link description here
Would this be relatively close?
Sub macro()
Dim wav_name As String
Range("A1").Select
Do While ActiveCell.Value <> ""
ActiveCell.Offset(0, 2).Select
wav_name = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Do
If ActiveCell.Value = wav_name Then
ActiveCell.Offset(1, 0).Select
Else
Exit Do
End If
Loop
Range(ActiveCell.Offset(0, -2), ActiveCell.End(xlDown)).Select
Selection.Cut
ActiveCell.End(xlUp).Offset(0, 3).Select
ActiveSheet.Paste
Loop
Range("A1").Select
End Sub
What you have there is pretty workable with a one key exception.
Your cut selection is only grabbing the first row of data. You will need to change it to
Range(ActiveCell).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
To handle the variable number of columns, you can capture the last column in section one by adding a varabile (i.e. LastCol) and putting the following code in your Do Loop
LastCol = Activecell.End(xlToRight).Column
Then replace the 3 in your last offset statement with your variable
Note that you can refactor the code to remove many of the select statements (includeing the ones I have mentioned above) if you need to improve the preformance of your code, but what you have written will work for you.
EDIT: Here is what your end code would look like
Sub macro()
Dim wav_name As String
Dim LastCol as Long
Range("A1").Select
Do While ActiveCell.Value <> ""
ActiveCell.Offset(0, 2).Select
wav_name = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
LastCol = Activecell.End(xlToRight).Column
Do
If ActiveCell.Value = wav_name Then
ActiveCell.Offset(1, 0).Select
Else
Exit Do
End If
Loop
Range(ActiveCell.Offset(0, -2), ActiveCell.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Cut
ActiveCell.End(xlUp).Offset(0, LastCol +1).Select
ActiveSheet.Paste
Loop
Range("A1").Select
End Sub
I haven't tested this, so you may have to do some debugging... but it is now logically correct.