Search and extract between workbooks - excel

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.

Related

How to auto number rows if adjacent cell is not blank using VBA Excel?

I need to auto number rows if adjacent cell is not blank using VBA.
any one from below codes works perfectly , except if it counter blank cells.
as always, your support is much appreciated.
this the expected output
Sub Fill_Serial_Numbers_Option1()
Dim LastRow As Long
LastRow = Cells(Rows.count, "B").End(xlUp).Row
If LastRow > 2 Then
Range("A3:A" & Application.Max(2, LastRow)) = Evaluate("ROW(A1:A" & LastRow & ")")
End If
End Sub
Sub Fill_Serial_Numbers_Option2()
Dim LastRow As Long
LastRow = Cells(Rows.count, "B").End(xlUp).Row
If LastRow > 2 Then
With Range("A3:A" & LastRow)
.Cells(1, 1).value = 1
.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=1, Trend:=False
End With
End If
End Sub
Please, test the next code:
Sub testCountNonBlanks()
Dim sh As Worksheet, lastR As Long, arr, arrA, count As Long, i As Long
Set sh = ActiveSheet
lastR = sh.Range("B" & sh.rows.count).End(xlUp).row: count = 1
If lastR <= 2 Then Exit Sub
arr = sh.Range("B2:B" & lastR).value 'place the range in an array for faster iteration
arrA = sh.Range("A2:A" & lastR).value
For i = 1 To UBound(arr)
If arr(i, 1) <> "" Then arrA(i, 1) = count: count = count + 1
Next i
sh.Range("A2").Resize(UBound(arrA), 1).value = arrA
End Sub
If a formula (written in VBA) is allowed, you can use the next variant:
Sub testCountByFormula()
Dim sh As Worksheet, lastR As Long, rngB As Range
Set sh = ActiveSheet
lastR = sh.Range("B" & sh.rows.count).End(xlUp).row
Set rngB = sh.Range("B2:B" & lastR)
sh.Range("A2:A10").Formula = "=IF(B2<>"""",COUNTA(" & rngB.Address & ")-COUNTA(" & rngB.Address(0, 1) & ")+1,"""")"
End Sub
You don't need a macro to accomplish this. Assuming all you care about is blank or not, then you can use a formula like this in cell A9. =Counta($B$1:$B9) If you have formulas you can try to leverage something with COuntif.
You can use a loop from the first row to the last one, something like this:
Sub Fill()
Dim LastRow As Long
Dim Count As Integer
Dim Row As Integer
Count = 0
Row = 1
LastRow = Cells(Rows.Count, "B").End(xlUp).Row
Do While Row <= LastRow
If Not (Cells(Row, 2) = "") Then
Count = Count + 1
Cells(Row, 1) = Count
End If
Row = Row + 1
Loop
End Sub

Cannot insert rows above range?

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?

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

identify the last used cell and paste below

I'm a total novice with VBA. I have the following code which does a matching exercise and then pastes the relevant values into col. B. my issue is each time the code is used the col will change how can I add this to the module so that it looks for the last cell used in row 1 and pastes the values below.
Sub TransferData()
Dim i As Long, j As Long, lastrow1 As Long, lastrow2 As Long
Dim myname As String
Application.ScreenUpdating = False
lastrow1 = Sheets("Input Sheet").Range("B" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow1
myname = Sheets("Input Sheet").Cells(i, "B").Value
Sheets("Data").Activate
lastrow2 = Sheets("Data").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To lastrow2
If Sheets("Data").Cells(j, "A").Value = myname Then
Sheets("Input Sheet").Activate
Sheets("Input Sheet").Cells(i, "c").Copy
Sheets("Data").Activate
Sheets("Data").Cells(j, "B").Select
ActiveSheet.PasteSpecial
End If
Next j
Application.CutCopyMode = False
Next i
Application.ScreenUpdating = True
End Sub
any assistance with this would be appreciated.
You can replace your second For j = 2 To lastrow2 with the Match function.
Also, there is no need to Activate the sheets back and fourth all the time, just use fully qualified Ranges instead.
Code
Option Explicit
Sub TransferData()
Dim i As Long, j As Long, lastrow1 As Long, lastrow2 As Long
Dim myname As String
Dim MatchRng As Range
Application.ScreenUpdating = False
j = 2
With Sheets("Input Sheet")
lastrow1 = .Range("B" & .Rows.Count).End(xlUp).Row
' the 2 lines bellow should be outisde the loop
lastrow2 = Sheets("Data").Range("A" & Sheets("Data").Rows.Count).End(xlUp).Row
Set MatchRng = Sheets("Data").Range("A2:A" & lastrow2)
For i = 2 To lastrow1
myname = .Range("B" & i).Value
If Not IsError(Application.Match(myname, MatchRng, 0)) Then '<-- if successful Match
Sheets("Data").Range("B" & j).Value = .Range("C" & i).Value
j = j + 1
End If
Application.CutCopyMode = False
Next i
End With
Application.ScreenUpdating = True
End Sub

For 2 to LastRow - not working

It's like it doesn't read LastRow as a Number! Help!! this is my code:
Sub DD()
Dim rNum As Long
Dim LastRow As Long
LastRow = ActiveSheet.Range("A1").End(xlDown).Rows.Count
For rNum = 2 To LastRow
Select Case Range("D" & rNum).Value
Case "FXD"
Range("P" & rNum).FormulaR1C1 = "= RC[-13]"
Case Else
Range("P" & rNum).Value = -4
End Select
Next rNum
End Sub
Change this line:
LastRow = ActiveSheet.Range("A1").End(xlDown).Rows.Count
to this:
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlup).Row
You wanted Row rather than Rows.Count (which would always be 1 since you were referring to one cell) and it's generally better to go up from the bottom of the sheet, rather than down.

Resources