Copying data from a referenced workbook - excel

I am getting a subscript out of range error on the first if statement.
I had this working when it was all within the same Workbook just different sheets
I want it to reference a different workbook to gets it data from.
I did the tools -> reference -> "Report" workbook that way I know it is open.
Sub update_cell1_InProcess()
Dim lRow As Long
b = 31
lRow = Workbooks("Report.xlsm").Sheets("CopyDatabase").Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lRow
If Workbooks("Report.xlsm").Sheets("CopyDatabase").Cells(i, 5).Value = Workbooks("Big screen.xlsm").Sheets("CELL_1").Cells()(1, 2).Value Then 'B1
If Workbooks("Report.xlsm").Sheets("CopyDatabase").Cells(i, 1).Value = Workbooks("Big screen.xlsm").Sheets("CELL_1").Cells()(1, 1).Value Then 'A1
If Workbooks("Report.xlsm").Sheets("CopyDatabase").Cells(i, 6).Value <> "" Then 'not blank
If Workbooks("Report.xlsm").Sheets("CopyDatabase").Cells(i, 8).Value = "" Then
Workbooks("Report.xlsm").Sheets("CopyDatabase").Rows(i).Copy
Workbooks("Big screen.xlsm").Sheets("SHEET1").Activate
Workbooks("Big screen.xlsm").Sheets("SHEET1").Cells(b + 1, 1).Select
ActiveSheet.Paste
b = b + 1
End If
End If
End If
End If
Next
Application.CutCopyMode = False
End Sub
Just different If statements but code that worked in same workbook different sheets
Sub update_cell1_completed()
Dim lRow As Long
b = 1
lRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lRow
If Worksheets("TEST").Cells(i, 5).Value = Worksheets("CELL_1").Cells()(1, 2).Value Then 'B1
If Worksheets("TEST").Cells(i, 1).Value = Worksheets("CELL_1").Cells()(1, 1).Value Then 'A1
If Worksheets("TEST").Cells(i, 6).Value <> "" Then 'not blank
If Worksheets("TEST").Cells(i, 8).Value <> "" Then 'not blank
Worksheets("TEST").Rows(i).Copy
Worksheets("SHEET1").Activate
Worksheets("SHEET1").Cells(b + 1, 1).Select
ActiveSheet.Paste
b = b + 1
End If
End If
End If
End If
Next
Application.CutCopyMode = False
End Sub

Here's your code refactored to include proper object references and simply the multi-if statement. See if you get the same error, and if so, let us know which line is erroring for you:
EDIT: Per comments, updated references to Workbooks("Big screen.xlsm") to instead be ThisWorkbook
Sub update_cell1_InProcess()
Dim wbRprt As Workbook: Set wbRprt = Workbooks("Report.xlsm")
Dim wbScrn As Workbook: Set wbScrn = ThisWorkbook
Dim wsDB As Worksheet: Set wsDB = wbRprt.Worksheets("CopyDatabase")
Dim wsC1 As Worksheet: Set wsC1 = wbScrn.Worksheets("CELL_1")
Dim wsS1 As Worksheet: Set wsS1 = wbScrn.Worksheets("SHEET1")
Dim lLastRow As Long: lLastRow = wsDB.Cells(wsDB.Rows.Count, "A").End(xlUp).Row
Dim lDestRow As Long: lDestRow = 32
Dim i As Long
For i = 1 To lLastRow
If wsDB.Cells(i, "E").Value = wsC1.Range("B1").Value _
And wsDB.Cells(i, "A").Value = wsC1.Range("A1").Value _
And Len(wsDB.Cells(i, "F").Value) > 0 _
And Len(wsDB.Cells(i, "H").Value) > 0 Then
wsDB.Rows(i).Copy wsS1.Cells(lDestRow, "A")
lDestRow = lDestRow + 1
End If
Next i
Application.CutCopyMode = False
End Sub

Related

Refer to a workbook that is closed

Problem:
I am working on the "Extract" workbook and expect to copy some data from the "Sales2021" workbook which is closed. The point is: when I have 2 workbooks open, the code works perfectly but when I close "Sales2021", it runs into error. My purpose is to modify the script so that even when "Sales2021" is closed, it still works.
Code explanations:
"Extract" contains 2 sheets, sheet1 and sheet2 (sheet2 is the destination sheet where I want to copy data from "Sales2021" to). "Sales2021" has only "Master_data" sheet. I want to check whether cells (1,2) and (1,3) of sheet1 match data in column 2 and 3 of "Master_data".
Sub Extract()
Dim LastRow As Long
Dim i As Long, j As Long
'Find the last used row in Column A
With Workbooks("Sales2021.xlsm").Sheets("Master_data")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
'Copy headers
Worksheets("Extract").Rows(1).Value = Workbooks("Sales2021.xlsm").Sheets("Master_data").Rows(1).Value
'first row number'
With Worksheets("Sheet2")
j = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
For i = 1 To LastRow
With Workbooks("Sales2021.xlsm").Sheets("Master_data")
If (.Cells(i, 2).Value = Worksheets("Sheet1").Cells(1, 1).Value And .Cells(i, 3).Value = Worksheets("Sheet1").Cells(1, 2).Value) Or (.Cells(i, 2).Value = Worksheets("Sheet1").Cells(1, 1).Value And Worksheets("Sheet1").Cells(1, 2).Value = "") Then
.Rows(i).Copy Destination:=Worksheets("Sheet2").Range("A" & j)
j = j + 1
End If
End With
Next i
End Sub
I haven't really tested this. The code checks if the workbooks is already open and opens it if needed.
Public Sub Extract()
Const EXPECTED_PATH As String = "C:\Users\Laura\Test\Sales2021.xlsm.xlsx"
'Check if the file is already open, if it isn't then open it.
Dim ReportBk As Workbook
Dim wrkBk As Workbook
For Each wrkBk In Application.Workbooks
If wrkBk.FullName = EXPECTED_PATH Then
Set ReportBk = wrkBk
Exit For
End If
Next wrkBk
If wrkBk Is Nothing Then
Set ReportBk = Workbooks.Open(EXPECTED_PATH)
End If
Dim Source_LastRow As Long
With ReportBk.Worksheets("Master_data")
Source_LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Worksheets("Extract").Rows(1).Value = .Rows(1).Value
End With
Dim Target_LastRow As Long
With ThisWorkbook.Worksheets("Sheet2")
Target_LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
End With
With ReportBk.Worksheets("Master_data")
Dim i As Long
For i = 1 To Source_LastRow
If (.Cells(i, 2).Value = Worksheets("Sheet1").Cells(1, 1).Value And _
.Cells(i, 3).Value = Worksheets("Sheet1").Cells(1, 2).Value) Or _
(.Cells(i, 2).Value = Worksheets("Sheet1").Cells(1, 1).Value And _
Worksheets("Sheet1").Cells(1, 2).Value = "") Then
.Rows(i).Copy Destination:=Worksheets("Sheet2").Cells(Target_LastRow, 1)
Target_LastRow = Target_LastRow + 1
End If
Next i
End With
End Sub

VBA code only works when I run it steps by steps(F8)

I have a code when runs perfectly by hitting F8 (running steps by steps). However, it doesn't work when hitting F5(running it). I guess it's because my code is kind of in loop but I couldn't figure out what's wrong.
Sub BLKReport()
Dim IRow As Long
Dim lcntr As Long
Dim ws As Worksheet
Dim ws1 As Worksheet
Dim b As Long
Dim r As String
Dim i As Long
Set ws = ThisWorkbook.Worksheets("CSV File")
Set ws1 = ThisWorkbook.Worksheets("Destination")
lrow = Range("A2").End(xlDown).Row
For lcntr = lrow To 1 Step -1
If ws.Cells(lcntr, 9).Value = "25" Then
r = ws.Cells(lcntr, 2).Value
For i = lcntr To 1 Step -1
If ws.Cells(i, 2).Value = r Then
ws.Rows(i).Copy
ws1.Activate
b = i
ws1.Cells(b - 1, 1).Select
ActiveSheet.Paste
ws.Activate
ElseIf ws.Cells(i + 1, 1).Value <> r Then
End If
Next i
End If
Application.CutCopyMode = False
ws.Select
Next
End Sub

How to return cell value with For Next loop using 2 sheets and multiple conditions - VBA

I'm attempting to match values between two sheets and if found and the conditions are met, perform the action of changing the cell colour.
PROBLEM:
I'm getting an error with my For...Next loop, even though I thought I have a NEXT for each FOR statement. Not sure what I've done wrong.
Also, I'm not sure my counters are setup correctly to accurately scan through each sheet/column needed. Any help would be appreciated.
Sub ReadData()
Dim wb As Workbook
Dim ws As Worksheet
Dim lastrow As Long
Dim i As Long
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Ref1")
Set ws2 = wb.Sheets("TRA")
lastrow = Sheets("Ref1").Cells(Rows.Count, "A").End(xlUp).Row
lastrow2 = Sheets("TRA").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Ref1").Activate
i = 2
k = 2
For i = 2 To lastrow
For k = 2 To lastrow2
If Cells(i, 4).Value = "Active" Then
If ws.Cells(i, 18).Value = ws2.Cells(i, 1).Value And (ws2.Cells(i, 23).Value <> "Cancelled" Or ws2.Cells(i, 23).Value <> "Completed") Then
Cells(i, 20).Interior.ColorIndex = 9
End If
Next
Next
End Sub
Quick Repair
To better understand the code, it is often preferable to use letters,
instead of numbers, for columns.
The Code
Sub ReadData()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim lastrow As Long
Dim lastrow2 As Long
Dim i As Long
Dim k As Long
' Use ThisWorkbook instead of ActiveWorkbook, if the code is
' in the same workbook where these sheets are.
With ActiveWorkbook
Set ws = .Worksheets("Ref1")
Set ws2 = .Worksheets("TRA")
End With
lastrow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
lastrow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastrow
If ws.Cells(i, "D").Value = "Active" Then
For k = 2 To lastrow2
If ws.Cells(i, "R").Value = ws2.Cells(k, "A").Value _
And ws2.Cells(k, "W").Value <> "Cancelled" _
And ws2.Cells(k, "W").Value <> "Completed" Then
ws.Cells(i, "T").Interior.ColorIndex = 9 ' Brown
Exit For
End If
Next
End If
Next
End Sub

Copy & paste each unique value from one sheet to another

I may have up to 8 unique values in column D. I am looking for a code that will copy & paste each row with unique value to a new sheet.
So I may have up to 8 new sheets.
Could you help me to build the code that will do that?
This is what I have so far:
Option Explicit
Sub AddInstructorSheets()
Dim LastRow As Long, r As Long, iName As String
Dim wb As Workbook, ws As Worksheet, ts As Worksheet, nws As Worksheet
Dim i As Integer
Dim m As Integer
'set objects
Set wb = ActiveWorkbook
Set ws = ActiveSheet
Set ts = Sheets("Master")
'set last row of instructor names
LastRow = ws.Cells(ws.Rows.Count, "K").End(xlUp).Row
'add instructor sheets
On Error GoTo err
Application.ScreenUpdating = False
For r = 17 To LastRow 'assumes there is a header
iName = ws.Cells(r, 4).Value
With wb 'add new sheet
ts.Copy After:=.Sheets(.Sheets.Count) 'add template
Set nws = .Sheets(.Sheets.Count)
nws.Name = iName
Worksheets(iName).Rows("17:22").Delete
Worksheets("Master").Activate
Range(Cells(r, 2), Cells(r, 16)).Select
Selection.Copy
m = Worksheets(iName).Range("A15").End(xlDown).Row
Worksheets(iName).Cells(m + 1, 1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
Next r
err:
ws.Activate
Application.ScreenUpdating = True
End Sub
The thing is that this macro is creating new sheets, which is not necessary. I only want to make following.
If you find a unique value in column D (which will have exact name as other sheet), find this sheet and paste whole row in there.
Sub CopyFromColumnD()
Dim key As Variant
Dim obj As Object
Dim i As Integer, lng As Long, j As Long
Dim sht As Worksheet, mainsht As Worksheet
Set obj = CreateObject("System.Collections.ArrayList")
Set mainsht = ActiveSheet
With mainsht
lng = .Range("D" & .Rows.Count).End(xlUp).Row
With .Range("D1", .Range("D" & lng))
For Each key In .Value
If Not obj.Contains(key) Then obj.Add key
Next
End With
End With
For i = 0 To obj.Count - 1
Set sht = Sheets.Add(After:=Sheets(Sheets.Count))
sht.Name = obj(i)
For j = 1 To lng
If mainsht.Cells(j, 4).Value = obj(i) Then
mainsht.Rows(j).EntireRow.Copy Destination:=Range("A1")
Exit For
End If
Next
Next
End Sub
Ok, I did the workaround. I have created a list of unique values in a separate sheet.
Sub copypaste()
Dim i As Integer
Dim j As Integer
LastRow = Worksheets("Master").Range("D17").End(xlDown).Row
For i = 17 To LastRow
For j = 2 To 10
Workstream = Worksheets("Database").Cells(j, 5).Value
Worksheets("Master").Activate
If Cells(i, 4) = Worksheets("Database").Cells(j, 5).Value Then
Range(Cells(i, 2), Cells(i, 16)).Select
Selection.Copy
Worksheets(Workstream).Cells(1, 1).PasteSpecial Paste:=xlPasteValues
Else
End If
Next j
Next i
End Sub
Thank you everyone for help and your time!

Sort values from one workbook into correct worksheets in another workbook

I have a very basic question. I have a large Workbook with alot of listed information. I want to take out some of the information into a new workbook and sort it on the different worksheets. I am having some problems with making the code understand which tab I want the information to be placed into. the strName = Range(cell value) do not work and I do not really know what I am doing wrong. How can I make this works? Sorry about the very messy code.
Private Sub CommandButton1_Click()
Dim strName As String
Set sourceWq = Workbooks("SD KPIs 2014 onwards").Worksheets("VQN+Concessionn")
Set front = Workbooks("databank progging").Worksheets("Frontpage")
For l = 5 To 30
For i = 2 To 250000 'Goes through the sourceWq workbook
If front.Cells(l, 13).Value = sourceWq.Cells(i, 24).Value Then 'Finds correct supplier
strName = Range("l,13")
Sheets(strName).Select 'Selects the correct worksheet for the supplier
For j = 4 To 15 'Month
If sourceWq.Cells(i, 33).Value = Cells(7, j).Value Then
For n = 8 To 11 'The type of NCR
If sourceWq.Cells(i, 27).Value = Cells(n, 2).Value Then
Cells(n, j).Value = Cells(n, j).Value + 1
Else: End If
Next n
Else: End If
Next j
Else: End If
Next i
Next l
End Sub
I slightly rewrote your code without this loop For i = 2 To 250000 (I use Find method instead):
Private Sub CommandButton1_Click()
Dim strName As String
Dim sourceWq As Worksheet, front As Worksheet, sh As Worksheet
Dim rng As Range
Dim firstAddress As String
Dim wb1 As Workbook, wb2 As Workbook
Dim l As Long, i As Long, j As Long
Set wb1 = Workbooks("SD KPIs 2014 onwards")
Set wb2 = Workbooks("databank progging")
Set sourceWq = wb1.Worksheets("VQN+Concessionn")
Set front = wb2.Worksheets("Frontpage")
For l = 5 To 30
With sourceWq.Range("X2:X250000")
Set rng = .Find(front.Cells(l, 13).Value, LookIn:=xlValues)
End With
If Not rng Is Nothing Then
firstAddress = rng.Address
Do
strName = front.Cells(l, 13).Value
Set sh = wb2.Worksheets(strName)
With sh
For j = 4 To 15 'Month
If rng.Offset(, 9).Value = .Cells(7, j).Value Then
For n = 8 To 11 'The type of NCR
If rng.Offset(, 3).Value = .Cells(n, 2).Value Then
.Cells(n, j).Value = .Cells(n, j).Value + 1
End If
Next n
End If
Next j
End With
Set rng = .FindNext(rng)
Loop While Not rng Is Nothing And rng.Address <> firstAddress
End If
Next l
End Sub
strName = Range("l,13") should read strName = Cells(l,13)

Resources