I am trying to transpose every second and third row to columns B and C and then preferably delete the old rows so that I don't have two unused rows in B and C. I tried recording a macro, which worked for only the selection I made. Then I tried deleting the specific selections and replacing them with an offset range but I keep getting an error in the PasteSpecial line.
Sub SortRawData()
'
' SortRawData Macro
'
' Keyboard Shortcut: Ctrl+q
'
Selection.Offset(1, 0).Resize(Selection.Rows.Count + 2, _
Selection.Columns.Count).Select
ActiveCell.Copy
ActiveCell.Offset(-1, 1).Select
ActiveCell.PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End Sub
I tried initially using Selection everywhere I have ActiveCell but neither seemed to work. I know I am missing the selection for the two rows I want to delete after I transpose the data into column B and C. What I have is a raw data dump of information that is formatted as:
Item1 Weight1 Color1 Item2 Weight2 Color2 Item 3 Weight 3 Color 3
I can get it to transpose one selection at a time by I can't seem to square away the automation of it.
Sub SortRawData2()
'
' SortRawData2 Macro
'
' Keyboard Shortcut: Ctrl+w
'
Selection.Copy
Range("B1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Rows("2:3").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End Sub
This is the initial recorded macro and even it fails debugging at the PasteSpecial line. Any suggestions would be much appreciated!
Thanks!
Try this, then code an autofilter to remove the empty rows:
Sub SortRawData2()
Dim lLastRow As Long, lLoop As Long
lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
For lLoop = 1 To lLastRow Step 3
Cells(lLoop, 2) = Cells(lLoop + 1, 1)
Cells(lLoop, 3) = Cells(lLoop + 2, 1)
Cells(lLoop + 1, 1).Resize(2).ClearContents
Next lLoop
With Range("A1:A" & lLastRow)
.AutoFilter field:=1, Criteria1:="="
.Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
End Sub
Related
I have an Excel Sheet wherein column "A" contains Serial numbers. One serial number may repeat to several rows. The cells in column "A" are merged [if more than one rows are appearing for One serial number]. I have made following macro to UN-merge these cells and repeat the serial number in subsequent blank rows until next serial number appears. The problem I am facing is that this macro is running very slow e.g. for a sheet containing 30,000 rows it may take a very long time. Is there a neat and less slower way to do it?
Here is the code I am using. Please guide.
Sub Unmerge_Cell()
Dim NumRows As Integer
Range("B2").Select
NumRows = Range("B2", Range("B2").End(xlDown)).Rows.Count
Columns("A:A").Select
Selection.UnMerge
Range("A2").Select
Range("A2").Activate
For i = 1 To NumRows - 1
If IsEmpty(ActiveCell.Offset(1, 0).Value) = True Then
ActiveCell.Select
Selection.Copy
ActiveCell.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Else
ActiveCell.Offset(1, 0).Select
ActiveCell.Offset(0, 0).Activate
End If
Next
Range("A1").Select
End Sub
Regards
This should be the fastest solution, no loop, simple.
Sub unMerge()
Dim lastRow As Long
lastRow = Range("B2").End(xlDown).Row
Range("A:A").unMerge
Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=r[-1]c"
With Range("A2:A" & lastRow)
.Value = .Value 'convert formula to constant
End With
End Sub
I tried to simplyfy your code. I haven't tested it in Excel ;-/
Sub Unmerge_Cell()
Dim NumRows As Integer
Dim i as Long
NumRows = Range("B2", Range("B2").End(xlDown)).Rows.Count
For i = 1 To NumRows - 1
If IsEmpty(Range("A2").Offset(i,0).Value) Then
Range("A2").Offset(i,0).Value = Range("A2").Offset(i-1,0).Value
End If
Next
End Sub
You can also turn off and turn on the screen updating when you macro is running
At the beginning on your code insert
application.screenupdating = false
And turn it on at the end
application.screenupdating = true
I have googled and tried various different things to get this to work but still can't find a solution.
I am still trying to learn about macros and VB so any help would be appreciated.
Basically, what I am after is a cell value on one worksheet to be the amount of rows on a second worksheet.
Picture showing what I am after
As described in the picture, the value of the source cell (number of payments) varies depending on the term/frequency/value of agreement.
I would then like that number of rows be allocated in the next worksheet, with sequential numbering.
This is what I have managed to fumble about with so far....
Sub ExtendByValue()
'
' ExtendByValue Macro
' Extends the rows by the number of repayments
'
'
Sheets("Agreement Tems").Select
Range("C8").Select
Selection.Copy
Sheets("Payments").Select
Range("M1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Rows("8:8").Select
Application.CutCopyMode = False
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End Sub
Any help with this is appreciated.
Rows("8:" & (sheets("agreementterms").range("c8").Value + 8)).select
Selection.insert shift:=xldown
incase you have value issues as specified in comments use the below.
Rows("8:" & (sheets("agreementterms").range("c8").text + 8)).select
Selection.insert shift:=xldown
try this
Option Explicit
Sub ExtendByValue()
'
' ExtendByValue Macro
' Extends the rows by the number of repayments
'
Dim nRows As Long
nRows = CLng(Sheets("Agreement Tems").Range("C8")) 'get the integer part of cell "C8" value in "Agreement Tems" sheet
With Sheets("Payments")
.Range("B8").Resize(nRows - 1).EntireRow.Insert 'insert nRows-1 below cell "B8" of "Payments" sheet, so as to have nRows with this latter included
With .Range("B8").Resize(nRows) 'of these nRows ...
.FormulaR1C1 = "=row()- row(R7)" ' ... fill column "B" with a formula returning integer form 1 to nRows ...
.Value = .Value ' ... and finally get rid of formulas and leave only values
End With
End With
End Sub
I know almost nothing about VBA and need some help! I've recorded a simple macro that will insert a row and perform some relative cut/paste when a certain value ("Choice") is found in column B. I would like this macro to loop until it reaches the end of the data set (keep in mind part of the macro inserts more rows as it goes). I've gotten it to loop and do what I want, but I can't figure out how to make it stop and not be infinite. Searching for blanks will not help as there are several blanks within the data set. Hoping for a helpful Do Until code? If you have a solution, can you please append it to my macro in your reply so I can see how the whole thing would look? Thank You!!
Sub Macro6()
'
' Macro6 Macro
' Spacer
'
' Keyboard Shortcut: Ctrl+q
'
Dim c As Range
For Each c In Range("B1:B3000")
Cells.Find(What:="choice", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ActiveCell.Offset(1, 0).Range("A1:B1").Select
Selection.Cut
ActiveCell.Offset(-1, 0).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(1, 0).Range("A1").Select
Next
End Sub
Sub Macro6()
'
' Macro6 Macro
' Spacer
'
' Keyboard Shortcut: Ctrl+q
'
Dim c As Range
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.count, "B").End(xlUp).Row
For I = lastRow To 1 Step -1
Debug.Print .Cells(I, 2).Value
If InStr(1, .Cells(I, 2).Value, "choice") > 0 Then
.Cells(I, 2).Rows("1:1").EntireRow.Select
Selection.Insert Shift:=xlDown
ActiveCell.Offset(1, 0).Range("A1:B1").Select
Selection.Cut
ActiveCell.Offset(-1, 0).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(1, 0).Range("A1").Select
End If
Next
End With
End Sub
When I run this code against this input ...
I get this output ...
Is this the result you were looking for? If not, can you provide a better description of the result you need?
I am working on an excel sheet and need to move the same range over and over again to the column "P" + 2
So the next range would be "C15:G15" to "P14". I'm looking for a slimmer solution than to repeat this code and change the ranges for hundreds of times..
ActiveWindow.SmallScroll Down:=-3
Range("C13:G13").Copy
Application.CutCopyMode = False
Selection.Copy
Range("P12").Select
Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
, SkipBlanks:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
This quick snippet should walk down every second row in column C starting at row 13 till the last populated cell in column C.
Sub move_CG_to_PT()
Dim rw As Long
With Worksheets("Sheet4") '<~~set this worksheet reference properly!
For rw = 13 To .Cells(.Rows.Count, "C").End(xlUp).Row Step 2
.Cells(rw - 1, "P").Resize(1, 5) = _
.Cells(rw, "C").Resize(1, 5).Value
Next rw
End With
End Sub
This only transfers the values. If the formatting and/or theme is critical then those could be adjusted for with the following.
Sub move_CG_to_PT_w_Formatting()
Dim rw As Long
With Worksheets("Sheet4") '<~~set this worksheet reference properly!
For rw = 13 To .Cells(.Rows.Count, "C").End(xlUp).Row Step 2
.Cells(rw, "C").Resize(1, 5).Copy _
Destination:=.Cells(rw - 1, "P")
Next rw
End With
End Sub
I am trying to select columns E and K from sheet Input, process in Working sheet and paste in the Output sheet after the last used row. I have stored the last used row number in x and paste the values in x+1 cell. However excel selects last row of the sheet (x as 65536) and gives run time error 4004. Can someone please help me in assisting the code.
Dim x As Long, y As String
Sheets("Input").Activate
Range("E:E,K:K").Select
Range("K1").Activate
Selection.Copy
Sheets("Working").Select
Cells(1, 1).Select
ActiveSheet.Paste
Cells.Select
Application.CutCopyMode = False
Selection.AutoFilter
Range("B5").Select
ActiveSheet.Range("$A$1:$H$30").AutoFilter Field:=1, Criteria1:="="
Cells.Select
Selection.Delete Shift:=xlUp
Columns("B:B").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B2").Select
ActiveCell.FormulaR1C1 = _
"=IF(RC[-1]="""","""",VLOOKUP(RC[-1],Repository!C[-1]:C[1],3,0))"
Range("B2").Select
Selection.Copy
Range("B3:B30").Select
ActiveSheet.Paste
Cells.Select
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("B2:C2").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Output").Select
Range("A1").Select
x = Worksheets("Output").UsedRange.Rows.Count
y = "a" & Trim(x + 1)
ActiveSheet("Output").Range(y).Select
ActiveSheet.Paste
Your UsedRange is still thinking that the last row is 65536. Add this subroutine, then call it right before you set x.
Sub CorrectUsedRange()
Dim values
Dim usedRangeAddress As String
Dim r As Range
'Get UsedRange Address prior to deleting Range
usedRangeAddress = ActiveSheet.UsedRange.Address
'Store values of cells to array.
values = ActiveSheet.UsedRange
'Delete all cells in the sheet
ActiveSheet.Cells.Delete
'Restore values to their initial locations
Range(usedRangeAddress) = values
End Sub
Near the bottom of your code replace:
Sheets("Output").Select
with:
Sheets("Output").Select
ActiveSheet.UsedRange
this should "re-set" UsedRange
Sometimes the Used Range gets generically large and won't reset on it's own. When this happens, the only way that I've found to force it to reset itself correctly is to Save the Workbook that the subject Worksheet is in. This works for me, on Excel 2010 anyway. Since you're using .Select and Active<obj> (which I don't recommend), it would simply be this:
ActiveWorkbook.Save
I would use a Find loop to populate an array and then output the array when the macro has completed. There is no need for a "Working" sheet. This also uses Cells(Rows.Count, "A").End(xlUp) in order to find the last populated row instead of UsedRange.Rows.Count which can be unreliable.
Sub tgr()
Dim rngFound As Range
Dim rngLookup As Range
Dim arrResults() As Variant
Dim ResultIndex As Long
Dim strFirst As String
With Sheets("Input").Columns("E")
Set rngFound = .Find("*", .Cells(.Cells.Count), xlValues, xlWhole)
If Not rngFound Is Nothing Then
strFirst = rngFound.Address
ReDim arrResults(1 To WorksheetFunction.CountA(.Cells), 1 To 2)
Do
If rngFound.Row > 1 Then
ResultIndex = ResultIndex + 1
On Error Resume Next 'Just in case the VLookup can't find the value on the 'Repository' sheet
arrResults(ResultIndex, 1) = Evaluate("VLOOKUP(""" & rngFound.Value & """,Repository!A:C,3,FALSE)")
arrResults(ResultIndex, 2) = .Parent.Cells(rngFound.Row, "K").Value
On Error GoTo 0 'Remove the On Error Resume Next condition
End If
Set rngFound = .Find("*", rngFound, xlValues, xlWhole)
Loop While rngFound.Address <> strFirst
End If
End With
If ResultIndex > 0 Then Sheets("Output").Cells(Rows.Count, "A").End(xlUp).Offset(1).Resize(ResultIndex, UBound(arrResults, 2)).Value = arrResults
Set rngFound = Nothing
Erase arrResults
End Sub
instead of used range check how many rows already are filled with this code:
X = WorksheetFunction.CountA(Columns(1))
Of course this only works ok if you have no rows that are empty in Column A, as those rows would be ignored!