Is there a way to automate checking a cell (in this case a year i.e. 2008 to 2013) and when a match is made execute a cut and paste, essentially sorting the data found in a range of cells (just to the right of the year) into columns? further along in the same row.
Edit
Ok Team I seem to have figured out how to do it manually, see an abbreviated portion of code
If ActiveCell = 2013 Then
ActiveCell.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=24
ActiveCell.Offset(0, 24).Range("A1").Select
ActiveSheet.Paste
End If
If ActiveCell = 2012 Then
ActiveCell.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=18
ActiveCell.Offset(0, 18).Range("A1").Select
ActiveSheet.Paste
End If
Now how to automate?
Second Edit...
Ok team I have solved the problem with the following code, thanks to the guys here in pointing me in the right direction.... great job...
Option Explicit
Sub NoTears()
Dim c As Range
Dim lastrow As Long
lastrow = Range("F" & Rows.Count).End(xlUp).Row
For Each c In Range("F1:C" & lastrow)
Select Case c.Value
'Case Is = 2009
' c.Offset(0, 2).Resize(1, 5).Cut Cells(Rows.Count, "??") _
.End(xlUp).Offset(1)
Case Is = 2010
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=8
c.Offset(0, 8).Range("A1").Select
ActiveSheet.Paste
Case Is = 2011
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=14
c.Offset(0, 14).Range("A1").Select
ActiveSheet.Paste
Case Is = 2012
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=20
c.Offset(0, 20).Range("A1").Select
ActiveSheet.Paste
Case Is = 2013
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=26
c.Offset(0, 26).Range("A1").Select
ActiveSheet.Paste
End Select
Next
End Sub
I would do something like this:
Not Tested
Dim Cell As Range
Dim lastRow as Long
lastRow = Range("F:F").Find("*", Range("F4"), searchdirection:=xlPrevious).Row 'this finds the last row in column F that contains data
For Each Cell In Range("F4:F" & lastrow) 'Loop through the whole table
Select Case Cell
Case 2008 'If the cell contains 2008 then...
lastRow = Range("AD:AD").Find("*", Range("AD4"),searchdirection:=xlPrevious).Row 'Find the last used row in your new table
Range(Cells(Cell.Row,8),Cells(Cell.Row,12).Copy Cells(lastRow + 1,30) 'Copy/paste the data into your new table
Case 2009
'Same concept as before
End Select
Next Cell
Not Tested
You will need to modify this to suit your needs. Specifically you'll need to update the column and offset numbers to match your data and tables correctly (I tried my best guess but I could be off).
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 an Excel macro that uses a function. Currently, the file is on a network drive. Data is pasted to the Excel file (new tab each time) and the macro is run with no problems (account number successfully pulled from larger data set).
In my effort to move the macro from a network drive to the cloud and run the macro from a separate Excel file (the file that contains the initial data dump i.e. no pasting data to file where macro lives), the portion of the macro that uses the function is now returning #NAME? instead of the proper numerical values. I am totally stumped as to why this is happening.
Literally any help at all is appreciated!
Function
Function onlynumbers(ByVal ref As String)
Dim rx As Object
Set rx = CreateObject("VBScript.RegExp")
With rx
.Pattern = "\D"
.Global = True
onlynumbers = .Replace(ref, "")
End With
End Function
Macro (see 'Fix Account Number' section)
Sub FORMAT()
'Remove extra rows on TOP
Rows("1:6").Select
Selection.Delete Shift:=xlUp
'Remove Extra Columns
Columns("A:H").Select
Selection.Delete Shift:=xlToLeft
Columns("B:O").Select
Selection.Delete Shift:=xlToLeft
Columns("C:J").Select
Selection.Delete Shift:=xlToLeft
'Extract Account Number from OBI Field
Range("C2").Select
ActiveCell.Formula = "=MID(B2,SEARCH(""79*"",B2),8)"
'Autofill Formula
Dim lastRow As Long
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Range("C2").AutoFill Destination:=Range("C2:C" & lastRow)
'Fix Account Number
Range("D2").Select
ActiveCell.Formula = "=onlynumbers(C2)"
Range("D2").AutoFill Destination:=Range("D2:D" & lastRow)
Range("E2").Select
ActiveCell.Formula = "=IF(LEN(D2)<6,"""",D2)"
Range("E2").AutoFill Destination:=Range("E2:E" & lastRow)
Range("E2:E" & lastRow).Select
Selection.Copy
Range("B2:B" & lastRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("C:D").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Columns("C:C").Select
Selection.Delete Shift:=xlToLeft
'Column Headers
Range("A1:G1").Value = Array("Amount", "Account", "Transaction Type", "Description", "Cash Type", "Post Date", "Tax Year")
'Switch Amount and Account Columns
Columns("B:B").Select
Selection.Cut
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
'Set Transaction Type
Range("C2").Value = "Deposit to Account - Wire received"
Range("C2").AutoFill Destination:=Range("C2:C" & lastRow)
'Set Description
Range("D2").Value = "$TranDesc$ of $CashAmount$"
Range("D2").AutoFill Destination:=Range("D2:D" & lastRow)
'Set Cash Type
Range("E2").Value = "Principal"
Range("E2").AutoFill Destination:=Range("E2:E" & lastRow)
'Set Post Date
Range("F2").Select
ActiveCell.Formula = "=TODAY()"
Range("F2").AutoFill Destination:=Range("F2:F" & lastRow)
'Set Tax Year
Range("G2").Select
ActiveCell.Formula = "=YEAR(TODAY())"
Range("G2").AutoFill Destination:=Range("G2:G" & lastRow)
'Final Formatting
Range("C1:G1").Select
Selection.Font.Bold = True
Columns("C:G").Select
Columns("C:G").EntireColumn.AutoFit
'Reset Selection
Range("A1").Select
End Sub
Did you also move your function, or just the macro?
If not, putting the function in the same place as the macro (just after End Sub on a new line) should fix things if you need the macro to refer to the function.
However, to use the function in a worksheet (which it looks like you are doing), the workbook containing the cell with the fixed account number needs to also contain the function. That way, the account number cell can use the function.
The error NAME is because the cell formula cannot find a defined name onlynumbers.
You could also try defining the function with the Name Manager instead of in VBA, but the best way might be to just change the formula in that cell to do what you want it to do using the built-in Excel functions. You could then update the macro to input this new formula at that line.
I'm stuck on this, I don't understand why the code adds those extra zeros in column D; What am I doing wrong?
Code: https://pastebin.com/ccpqPJdz
last = Range("B" & Rows.Count).End(xlUp).Row
'Insert 3 columns on left. Add information in Row 1, add data in column D.
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Columns("E:E").Copy Destination:=Columns("C:C")
Columns("E:E").Select
Selection.Delete Shift:=xlToLeft
Range("D2:D2" & last).Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.FormulaR1C1 = "=R[-1]C[6]"
Columns("D").Copy
Columns("D").PasteSpecial xlPasteValues
Range("D1") = Time
Range("D1").NumberFormat = "h:mm:ss"
Input:
Output:
Avoid the Selection object. It's created as a medium of communication between the user and VBA via the screen. VBA has direct access to the Excel workbook and therefore doesn't need it. Please try this code.
Private Sub InsertThreeColumns()
Dim Rl As Long ' last used row
Dim Rng As Range
With Worksheets("NewTest") ' change to suit
Rl = .Cells(.Rows.Count, "B").End(xlUp).Row
.Columns(2).Copy
.Columns(1).Insert Shift:=xlToRight
Application.CutCopyMode = False
.Columns("A:B").Insert Shift:=xlToRight
.Columns(5).EntireColumn.Delete
On Error Resume Next
' next line will cause a crash if there are no blanks
Set Rng = .Range(.Cells(2, "D"), .Cells(Rl, "D")).SpecialCells(xlCellTypeBlanks)
If Err = 0 Then
Rng.FormulaR1C1 = "=R[-1]C[6]"
Rng.Copy
Rng.PasteSpecial xlPasteValues
End If
On Error GoTo 0
With .Cells(1, "D")
.Value = Time
.NumberFormat = "h:mm:ss"
End With
End With
End Sub
The extra zeroes that troubled you were caused by the method of defining the range where you wanted the formula to supply cell content. In your code that range is a derivative of a Selection. In the above code it's defined by starting cell and end cell. The result should be the same. It isn't because the route via the Selection object is circuitous and difficult to follow.
I'm trying to stop using ActiveCell etc as StackOverflow has very much declared this a "nono"
My current code is:
Sub SitesAndProd()
Set wb = ActiveWorkbook
Set ws = Worksheets("Data")
Set rng = ws.Cells(1, 13)
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
rng.FormulaR1C1 = "SitesAndProd" 'Rename Cell SitesAndProd
Set rng = ws.Cells(2, 13)
rng.FormulaR1C1 = "=RC[-12]&RC[-4]"
rng.Offset(0, -1).Select 'Move left 1 column
Selection.End(xlDown).Select 'Go to bottom of column
rng.Offset(0, 1).Select 'Move right 1 column
Range(Selection, Selection.End(xlUp)).Select 'Go to top of Column
Selection.FillDown 'Copy Formula Down "Fill"
Selection.Copy 'Ctrl + C
Selection.PasteSpecial xlPasteValues 'Right click + V
Application.CutCopyMode = False 'Esc (stops the crawling ants
End Sub
When using Selection.End(xlDown).Select and xlUp later - it's not saving the range position
What's the best way to make sure the range is kept here?
When using the following:
Range("M2").Select
ActiveCell.FormulaR1C1 = "=RC[-12]&RC[-4]"
Range("M2").Select
ActiveCell.Offset(0, -1).Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 1).Select
Range(Selection, Selection.End(xlUp)).Select
Selection.FillDown
The code will pull the correct form - going left 1, to the bottom, right 1, selecting up to to the, then copying down
Any chance that someone can point me in the right direction to be able to do this without ActiveCell, Selection and Select?
This is supposing the LastRow you calculated on column A equals the same amount of rows in column M
Option Explicit
Sub SitesAndProd()
Dim wb As Workbook, ws As Worksheet, LastRow As Long
Set wb = ThisWorkbook
Set ws = Worksheets("Data")
ws.Cells(1, 13) = "SitesAndProd"
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
With ws.Range(ws.Cells(2, 13), ws.Cells(LastRow, 13))
.FormulaR1C1 = "=RC[-12]&RC[-4]"
.Value = .Value
End With
End Sub
I've tweaked some of your code. You need to declare your variables, wb As Workbook and ws As Worksheet. If workbook is the one you got your code in, use ThisWorkbook instead ActiveWorkbook you will get less errors from that.
Edit: Try to avoid as much the global variables. Pass them on your subs or functions as variables.
I expect your code:
Range("M2").Select
ActiveCell.FormulaR1C1 = "=RC[-12]&RC[-4]"
Range("M2").Select
ActiveCell.Offset(0, -1).Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 1).Select
Range(Selection, Selection.End(xlUp)).Select
Selection.FillDown
can be replaced with:
Range(Range("M2"), Range("M" & ActiveSheet.Rows.Count).End(xlUp)).Formula = "=RC[-12]&RC[-4]"
If the column which you would like to use to determine the last filled cell is column Q:
Range(Range("M2"), Range("Q" & ActiveSheet.Rows.Count).End(xlUp).Row).Formula = "=RC[-12]&RC[-4]"
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.