Cannot insert rows above range? - excel

i wrote the following code, in order to paste the rngtocopy ABOVE rngins....
Now ive tried around a lot and it keeps adding it below the rngins and i have no idea why.
I tried out xlshiftup, which actually gives me errors, probably cause there are values above?
Sub reviewverschieben()
Dim counter As Long, lrow As Long, lrowrev As Long, i As Long, lastrev As Long
Dim ws As Worksheet
Dim rngtocopy As Range, rngins As Range
Dim lastcolumn As String
Set ws = ActiveSheet
Rows.EntireRow.Hidden = False
counter = 0
With ws
lrow = .Cells(Rows.Count, 1).End(xlUp).row
Do While counter = 0
For i = 32 To lrow
If .Cells(i, 1).Value = "Review Participants" And counter = 1 Then
lrowrev = i
ElseIf .Cells(i, 1).Value = "Review Participants" And i <> lrow Then
counter = counter + 1
lastrev = i 'row nr which we take as a reference to insert new table above
lrowrev = lastrev
lcol = .Cells(i + 1, .Columns.Count).End(xlToLeft).Column 'last meeting of the review is our reference for lastcol
ElseIf counter = 1 And i = lrow Then
lrowrev = lrow + 2
Exit For
End If
Next
Loop
lastcolumn = Split(Cells(, lcol).Address, "$")(1)
Set rngtocopy = .Range("A" & 32 & ":" & lastcolumn & lrowrev)
Debug.Print rngtocopy.Address
Set rngins = .Range("A" & 32 & ":" & lastcolumn & lrowrev)
Debug.Print rngins.Address
'Range("A" & lrow).Offset(5).EntireRow.Hidden = False
rngtocopy.Copy
rngins.Insert Shift:=xlShiftDown
ringins.PasteSpecial Paste:=xlPasteAll
Image for better clarification, what i have right now

If you need to make space for copying of rngins range you should proceed as following:
Dim aboveR As Long
aboveR = rngins.Cells(1, 1).row
sh.Rows(aboveR & ":" & aboveR + rngtocopy.Rows.Count - 1).Insert xlDown
This piece of code will insert above the rngins range as many rows as rngtocopy range has.
If you need to insert only some rows of the range, the second parameter will need to replace rngtocopy.Rows.Count with that specific number of rows. And then, the paste cell must be determined by adding that number to the existing aboveR value:
Dim pasteCell As Range
Set pasteCell = sh.Range("A" & aboveR + rngtocopy.Rows.Count)
rngtocopy.Copy pasteCell
And in order to make your code working in the way you wanted, try this:
rngtocopy.Copy
rngins.Cells(1, 1).Insert Shift:=xlDown
Application.CutCopyMode = False 'Clear clipboard
When you try to insert rows and there is something in clipboard, the clipboard content is inserted...

Your specification of RngIns may well be described as adventurous, considering this little piece of code juggling: lastcolumn = Split(Cells(, lcol).Address, "$")(1). I recommend that you define the range like this.
Set rngIns = .Range(.Cells(32, "A"), .Cells(lrowrev, lcol))
The code defines the first and last cells of the range and that makes it easy for you to follow. Now, if you insert at rngIns the insertion will be made below that range. If you insert at RngIns.Offset(1) the insertion will be made above rngIns. Of course, you can make that same difference by defining rngIns's row differently, perhaps like Set rngIns = .Range(.Cells(33, "A"), .Cells(lrowrev + 1, lcol)).
However, I wonder why you insert cells at all. Wouldn't it be easier to insert so many sheet rows and then paste to the blank rows?

Related

Deleting Rows that contain criteria in specific columnn

Quick question.
I have this macro below which looks if column B contains a 0 value. In the instance that it does, it deletes that row. This works well until there are instances where no rows contain a zero, and then it throws an error saying it's out of range.
is it possible to tweak this so that it runs without an error, and just doesn't delete anything if it can't find a row with a 0 in Column B?
Sub Deletezero()
Dim LastRow As Long, ReadRow As Long, n As Long
With ThisWorkbook.Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
ReadRow = 1
For n = 1 To LastRow
If Range("B" & ReadRow).Value Like "*0*" = True Then
Range("H" & ReadRow).EntireRow.Delete
Else
ReadRow = ReadRow + 1
End If
Next
End Sub
Please, try the next code. It should be faster then yours, deleting all rows (if any to be deleted) at once, at the end. In fact, the code only select the rows. If the selection is correct, please replace Select with Delete:
Sub Deletezero()
Dim sh As Worksheet, LastRow As Long, n As Long, rngDel As Range
Set sh = ThisWorkbook.Sheets("Sheet1")
LastRow = sh.cells(sh.rows.count, "B").End(xlUp).row
For n = 1 To LastRow
If sh.Range("B" & n).Value Like "*0*" Then
If rngDel Is Nothing Then
Set rngDel = sh.Range("B" & n)
Else
Set rngDel = Union(rngDel, sh.Range("B" & n))
End If
End If
Next
If Not rngDel Is Nothing Then rngDel.EntireRow.Select 'if it selects what you need, please replace Select with Delete
End Sub

vba code to find a predetermined range, copy and transpose

I'm working on a excel document with multiple seperate data, all in a single column (A1 to A10160).
All the data begins in a cell with the text NC/xx/xxxx/x (x being variable) and ending in a cell containing different dates but the cell above it always has the text "Start Date". Some data covers 49 cells others cover 51 cells so it's not contained in a fixed number of cells in the column.
I need to copy the range from NC/xx/xxxx/x to Start Date plus one for each data "set", transpose it and paste all the data in the column in a new sheet.
Really haven't found anything useful so far but I am fumbling with this one:
Sub Find()
Dim Search, End, Start, i As Integer, j As Integer, L
Search = Cells(1, 1)
End = Cells(2, 1)
For i = 1 To 10160
If Left(Cells(i, 1), 3) = Search Then
Start = i - 0
End If
Next i
For j = 1 To 10160
If Cells(j, 1) = End Then
L = j + 1
End If
Sheet4.Select
Range(Cells(Start, 1), Cells(L + 2, 1)).Select
Selection.Copy
Sheet4.Range("BB23").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False
End
Next j
End Sub
Would really appreciate any help I can get!
Thanks!
It looks like you haven't had much interest in your question, so I've taken a look at it. It's one of those fiddly jobs - not terribly technical but tricky to get the flow of logic right. The code below gives you what you've outlined in your question. You've said transpose it - so that's what the code does. Try it and let me know how you go.
Option Explicit
Sub Copy2Sheet2()
'Declare all your variables
Dim ws1 As Worksheet, ws2 As Worksheet
Dim topRow As Long, BottomRow As Long, LastRow As Long
Dim PasteToRow As Long, i As Long, c As Range
'Set the sheet variables
Set ws1 = Sheets(1)
Set ws2 = Sheets(2)
'Initial row settings
LastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
PasteToRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 1 '<~~ assumes headers on sheet2
'Start the loop
For i = 1 To LastRow
'Find the bottom row of the first block of data
Set c = ws1.Range("A" & i & ":A" & LastRow).Find(What:="Start Date", LookIn:=xlValues)
BottomRow = c.Row + 1
'Define and copy the range to sheet2
ws1.Range("A" & i & ":A" & BottomRow).Copy
ws2.Range("A" & PasteToRow).PasteSpecial Transpose:=True
Application.CutCopyMode = False
'Redefine the 'paste to' row
PasteToRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 1
'Redefine the top row of the next block of data
i = BottomRow
'Repeat the process
Next i
End Sub

Macro - Copy CERTAIN Cells in Same Row, Triggered by a Checkbox, to Different Worksheet

Need some assistance. I have a template that gets data exported into it from a different program. The rows of data varies from export to export and a new workbook is needed for each export.
I, currently, have a 'Master' macro written that cleans up the worksheet (formats, text to numbers, etc.) and also adds checkboxes to the end of each row that contains data. These checkboxes are linked to a cell. Once the operator completes the worksheet, they will then need to check a checkbox for each row of data that is 'out of spec'. These rows will then be copied onto the next sheet in the workbook. This is triggered by a button. My current macro works other than copying the entire row of data when I only want to copy over cells in columns 'A' through 'I'. Cells in columns 'J' and out contain data that does NOT need to be copied.
Here is my current macro that, like I said, copies the entire row:
Sub CopyRows()
Dim LRow As Long, ChkBx As CheckBox, WS2 As Worksheet
Set WS2 = Worksheets("T2 FAIR (Single Cavity)")
LRow = WS2.Range("A" & Rows.Count).End(xlUp).Row
For Each ChkBx In ActiveSheet.CheckBoxes
If ChkBx.Value = 1 Then
LRow = LRow + 1
WS2.Cells(LRow, "A").Resize(, 14) = Range("A" & _
ChkBx.TopLeftCell.Row).Resize(, 14).Value
End If
Next
End Sub
In the right-side of your equation, your Range() object is not properly qualified (with a worksheet). So, I used the fake wsX in this example.
Also, I used the ending column of "D" - but you can change to whatever you need it to be.
LRow = LRow + 1
r = ChkBx.TopLeftCell.Row
ws2.Range(ws2.Cells(LRow, "A"), ws2.Cells(LRow, "D")) = wsX.Range( _
wsX.Cells(r, "A"), wsX.Cells(r, "D"))
or
ws2.Range("A" & LRow & ":D" & LRow) = wsX.Range("A" & r & ":D" & r)
From Comment:
The templates ALWAYS start, with the imported data, in "A19". When I run this macro, to copy the checked data to the next worksheet, it starts in with cell "A18". I have no idea as to why. How do I specify that the checked data is to be copied starting with "A19" on the next worksheet?
If it's always off by one, you can just add 1. I am not sure how your layout is, so this will be something you will have to either add to LRow or r. So either
ws2.Range("A" & LRow + 1 & ":D" & LRow + 1) = ...
or
... = wsX.Range("A" & r + 1 & ":D" & r + 1)
Answer is as follows:
Sub CopyRows()
Dim ws1 As Worksheet
Set ws1 = Worksheets("T1 FAIR (Single Cavity)")
Dim ws2 As Worksheet
Set ws2 = Worksheets("T2 FAIR (Single Cavity)")
Dim LRow As Long
LRow = ws2.Range("A" & rows.count).End(xlUp).row
Dim r As Long
Dim ChkBx As CheckBox
For Each ChkBx In ws1.CheckBoxes
If ChkBx.value = 1 Then
LRow = LRow + 1
r = ChkBx.TopLeftCell.row
ws2.Range("A" & LRow + 1 & ":I" & LRow + 1).value = _
ws1.Range("A" & r & ":I" & r + 1).value
End If
Next
End Sub

Search and extract between workbooks

I'm trying to use the following code to search one cell in each row. If the search value matches a portion of the cell in that row, the entire row is copied and added to the end of another range in another workbook.
Sub GetRowsWithMatchingDates ()
Dim toThisWorkSheet As Worksheet, fromSourceWorkbook As Workbook
Dim NextFreeRow As Long
Dim LastRow As Long
Dim currentRowDate As String
Dim currentRow As Long
Dim TodaysDateAsString As String
Dim currentRowDate As String
TodaysDateAsString = 20150320
Set toThisWorkSheet = ThisWorkbook.Sheets("ImportedData")
NextFreeRow = toThisWorksheet.Range("A" & Rows.Count).End(xlUp).Row + 1
Set fromSourceWorkbook = Workbooks.Open(ThisWorkbook.Path & "JUIDTesting.xlsb")
With fromSourceWorkBook.Sheets("DataToBeSearched")
For i = 1 to To LastRow
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
currentRowDate = Mid(toThisWorkbook.Range("B" & i + 1).Value, 3, 8)
currentRow = .Range("A" & i + 1).Row
If TodaysDateAsString = currentRowDate Then
currentRow.Copy
toThisWorkbook.Range("A" & LastRow + 1).PasteSpecial xlPasteValues
Endif
Next i
End With
fromSourceWorkBook.Close False
End Sub
`
I'm just beginning to use for and with and copy paste code so this could be totally jacked up.
lastrow needs to be before your loop, right now it is undefined and defaults to 0. So you are doing a for i = 1 to 0 esentially.
it should be
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 1 to To LastRow
currentRowDate = Mid(toThisWorkbook.Range("B" & i + 1).Value, 3, 8)
currentRow = .Range("A" & i + 1).Row
If TodaysDateAsString = currentRowDate Then
currentRow.Copy
toThisWorkbook.Range("A" & LastRow + 1).PasteSpecial xlPasteValues
Endif
Next i
That would correct your first problem.
Your second problem is that toThisWorkbook is not defined anywhere + it is in a with from source workbook, and you do not have a worksheet defined.
Would need to be something like
ThisWorkbook.toThisWorkSheet.Range("A" & LastRow + 1).PasteSpecial xlPasteValues
but also keep in mind that will just keep overwriting the same row because that is what you told it to do. lastrow + 1 = will always be the same constant.

Excel 2010 VBA. Concatenate 2 columns from a Sheet and paste them in another

Using Excel 2010, I'm trying to create a script that concatenates two text columns (A and B) from Sheet1 and pastes the result in column A of Sheet2.
The workbook uses an external datasource for loading both columns, so the number of rows is not fixed.
I've tried the following code, but not working. variable lRow is not taking any value.
Sub Concat()
Sheets("Sheet1").Select
Dim lRow As Long
lRow = Range("A" & Rows.count).End(xlUp).Row
For i = 2 To lRow
ActiveWorkbook.Sheets("Sheet2").Cells(i, 1) = Cells(i, 1) & Cells(i, 2)
Next i
End Sub
What am I doing wrong. Thanks for helping!
As to what are you doing wrong, I suggest you use
Sub Concat()
Sheets("Sheet1").Select
Dim lRow As Long, i As Long
Dim rng As Range
Set rng = Range("A" & Rows.Count).End(xlUp)
Debug.Print rng.Address(External:=True)
lRow = rng.Row
For i = 2 To lRow
ActiveWorkbook.Sheets("Sheet2").Cells(i, 1) = Cells(i, 1) & Cells(i, 2)
Next i
End Sub
to see what is going on. I tried exactly what you used and it worked for me (Excel 2010).
Specifying what does "variable lRow is not taking any value" mean would help.
You could also try alternatively
Sub Concat2()
Sheets("Sheet1").Select
Dim lRow As Long, i As Long
Dim rng As Range
Set rng = Range("A2").End(xlDown)
Debug.Print rng.Address(External:=True)
lRow = rng.Row
For i = 2 To lRow
ActiveWorkbook.Sheets("Sheet2").Cells(i, 1) = Cells(i, 1) & Cells(i, 2)
Next i
End Sub
which should give the same result if yo do not have blank cells in the middle of the source column A.
I would advise getting out of the .Select method of XL VBA programming in favor of direct addressing that will not leave you hanging with errors.
Sub Concat()
Dim i As Long, lRow As Long
With Sheets("Sheet1")
lRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lRow
Sheets("Sheet2").Cells(i, 1) = .Cells(i, 1) & .Cells(i, 2)
Next i
End With
End Sub
Note the periods (aka . or full stop) that prefix .Cells and .Range. These tell .Cells and .Range that they belong to the worksheet referenced in the With ... End With block; in this example that would be Sheets("Sheet1").
If you have a lot of rows to string together you would be better off creating an array of the values from Sheet1 and processing the concatenation in memory. Split off the concatenated values and return them to Sheet2.
Sub concat2()
Dim c As Long, rws As Long, vCOLab As Variant
With Sheets("Sheet1")
rws = .Range("A2:A" & .Cells(Rows.Count, 1).End(xlUp).Row).Rows.Count
vCOLab = .Range("A2").Resize(rws, 3)
For c = LBound(vCOLab, 1) To UBound(vCOLab, 1)
'Debug.Print vCOLab(c, 1) & vCOLab(c, 2)
vCOLab(c, 3) = vCOLab(c, 1) & vCOLab(c, 2)
Next c
End With
Sheets("Sheet2").Range("A2").Resize(rws, 1) = Application.Index(vCOLab, , 3)
End Sub
When interacting with a worksheet, bulk operations will beat a loop every time; the only question is by how much.

Resources