Can somebody help me with this code, I am getting a subscript out of range error:
The line after the 'creating the sheets is highlighted in yellow in debugger
'Validation of year
If TextBox_Year.Value = Format(TextBox_Year.Value, "0000") Then
'Creating Process
'Creation of new sheet
Workbooks.Add
ActiveWorkbook.SaveAs FileName:= _
"" & Workbooks("Temperature Charts Sheet Creator").Sheets("MENU").Cells(4, 12).Value & "Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value & ".xls", FileFormat _
:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:= _
False, CreateBackup:=False
'Creating of the sheets
Windows("Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value & ".xls").Activate
Sheets("Sheet3").Select
Sheets("Sheet3").Name = "31 " & ComboBox_Month.Value
Sheets("Sheet2").Select
Sheets("Sheet2").Name = "30 " & ComboBox_Month.Value
Sheets("Sheet1").Select
Sheets("Sheet1").Name = "29 " & ComboBox_Month.Value
For i = 28 To 1 Step -1
Sheets.Add
ActiveSheet.Name = i & " " & ComboBox_Month.Value
Next
Suggest the following simplification: capture return value from Workbooks.Add instead of subscripting Windows() afterward, as follows:
Set wkb = Workbooks.Add
wkb.SaveAs ...
wkb.Activate ' instead of Windows(expression).Activate
General Philosophy Advice:
Avoid use Excel's built-ins: ActiveWorkbook, ActiveSheet, and Selection: capture return values, and, favor qualified expressions instead.
Use the built-ins only once and only in outermost macros(subs) and capture at macro start, e.g.
Set wkb = ActiveWorkbook
Set wks = ActiveSheet
Set sel = Selection
During and within macros do not rely on these built-in names, instead capture return values, e.g.
Set wkb = Workbooks.Add 'instead of Workbooks.Add without return value capture
wkb.Activate 'instead of Activeworkbook.Activate
Also, try to use qualified expressions, e.g.
wkb.Sheets("Sheet3").Name = "foo" ' instead of Sheets("Sheet3").Name = "foo"
or
Set newWks = wkb.Sheets.Add
newWks.Name = "bar" 'instead of ActiveSheet.Name = "bar"
Use qualified expressions, e.g.
newWks.Name = "bar" 'instead of `xyz.Select` followed by Selection.Name = "bar"
These methods will work better in general, give less confusing results, will be more robust when refactoring (e.g. moving lines of code around within and between methods) and, will work better across versions of Excel. Selection, for example, changes differently during macro execution from one version of Excel to another.
Also please note that you'll likely find that you don't need to .Activate nearly as much when using more qualified expressions. (This can mean the for the user the screen will flicker less.) Thus the whole line Windows(expression).Activate could simply be eliminated instead of even being replaced by wkb.Activate.
(Also note: I think the .Select statements you show are not contributing and can be omitted.)
(I think that Excel's macro recorder is responsible for promoting this more fragile style of programming using ActiveSheet, ActiveWorkbook, Selection, and Select so much; this style leaves a lot of room for improvement.)
Subscript out of Range error occurs when you try to reference an Index for a collection that is invalid.
Most likely, the index in Windows does not actually include .xls. The index for the window should be the same as the name of the workbook displayed in the title bar of Excel.
As a guess, I would try using this:
Windows("Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value).Activate
Option Explicit
Private Sub CommandButton1_Click()
Dim mode As String
Dim RecordId As Integer
Dim Resultid As Integer
Dim sourcewb As Workbook
Dim targetwb As Workbook
Dim SourceRowCount As Long
Dim TargetRowCount As Long
Dim SrceFile As String
Dim TrgtFile As String
Dim TitleId As Integer
Dim TestPassCount As Integer
Dim TestFailCount As Integer
Dim myWorkbook1 As Workbook
Dim myWorkbook2 As Workbook
TitleId = 4
Resultid = 0
Dim FileName1, FileName2 As String
Dim Difference As Long
'TestPassCount = 0
'TestFailCount = 0
'Retrieve number of records in the TestData SpreadSheet
Dim TestDataRowCount As Integer
TestDataRowCount = Worksheets("TestData").UsedRange.Rows.Count
If (TestDataRowCount <= 2) Then
MsgBox "No records to validate.Please provide test data in Test Data SpreadSheet"
Else
For RecordId = 3 To TestDataRowCount
RefreshResultSheet
'Source File row count
SrceFile = Worksheets("TestData").Range("D" & RecordId).Value
Set sourcewb = Workbooks.Open(SrceFile)
With sourcewb.Worksheets(1)
SourceRowCount = .Cells(.Rows.Count, "A").End(xlUp).row
sourcewb.Close
End With
'Target File row count
TrgtFile = Worksheets("TestData").Range("E" & RecordId).Value
Set targetwb = Workbooks.Open(TrgtFile)
With targetwb.Worksheets(1)
TargetRowCount = .Cells(.Rows.Count, "A").End(xlUp).row
targetwb.Close
End With
' Set Row Count Result Test data value
TitleId = TitleId + 3
Worksheets("Result").Range("A" & TitleId).Value = Worksheets("TestData").Range("A" & RecordId).Value
'Compare Source and Target Row count
Resultid = TitleId + 1
Worksheets("Result").Range("A" & Resultid).Value = "Source and Target record Count"
If (SourceRowCount = TargetRowCount) Then
Worksheets("Result").Range("B" & Resultid).Value = "Passed"
Worksheets("Result").Range("C" & Resultid).Value = "Source Row Count: " & SourceRowCount & " & " & " Target Row Count: " & TargetRowCount
TestPassCount = TestPassCount + 1
Else
Worksheets("Result").Range("B" & Resultid).Value = "Failed"
Worksheets("Result").Range("C" & Resultid).Value = "Source Row Count: " & SourceRowCount & " & " & " Target Row Count: " & TargetRowCount
TestFailCount = TestFailCount + 1
End If
'For comparison of two files
FileName1 = Worksheets("TestData").Range("D" & RecordId).Value
FileName2 = Worksheets("TestData").Range("E" & RecordId).Value
Set myWorkbook1 = Workbooks.Open(FileName1)
Set myWorkbook2 = Workbooks.Open(FileName2)
Difference = Compare2WorkSheets(myWorkbook1.Worksheets("Sheet1"), myWorkbook2.Worksheets("Sheet1"))
myWorkbook1.Close
myWorkbook2.Close
'MsgBox Difference
'Set Result of data validation in result sheet
Resultid = Resultid + 1
Worksheets("Result").Activate
Worksheets("Result").Range("A" & Resultid).Value = "Data validation of source and target File"
If Difference > 0 Then
Worksheets("Result").Range("B" & Resultid).Value = "Failed"
Worksheets("Result").Range("C" & Resultid).Value = Difference & " cells contains different data!"
TestFailCount = TestFailCount + 1
Else
Worksheets("Result").Range("B" & Resultid).Value = "Passed"
Worksheets("Result").Range("C" & Resultid).Value = Difference & " cells contains different data!"
TestPassCount = TestPassCount + 1
End If
Next RecordId
End If
UpdateTestExecData TestPassCount, TestFailCount
End Sub
Sub RefreshResultSheet()
Worksheets("Result").Activate
Worksheets("Result").Range("B1:B4").Select
Selection.ClearContents
Worksheets("Result").Range("D1:D4").Select
Selection.ClearContents
Worksheets("Result").Range("B1").Value = Worksheets("Instructions").Range("D3").Value
Worksheets("Result").Range("B2").Value = Worksheets("Instructions").Range("D4").Value
Worksheets("Result").Range("B3").Value = Worksheets("Instructions").Range("D6").Value
Worksheets("Result").Range("B4").Value = Worksheets("Instructions").Range("D5").Value
End Sub
Sub UpdateTestExecData(TestPassCount As Integer, TestFailCount As Integer)
Worksheets("Result").Range("D1").Value = TestPassCount + TestFailCount
Worksheets("Result").Range("D2").Value = TestPassCount
Worksheets("Result").Range("D3").Value = TestFailCount
Worksheets("Result").Range("D4").Value = ((TestPassCount / (TestPassCount + TestFailCount)))
End Sub
Related
I am making a tool in excel VBA to bulk create some kind of invoices to each customer. We are making LIVE streams and selling kids clothing, then we write all our orders to excel sheet. Example:
orders list
Then we have to sort all those orders by customer (there are many of them) and create some kind of invoice for each customer. Example: "invoice template"
I use this code to bulk create those and download as pdfs.
Sub Create_PDF_Files()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim dsh As Worksheet
Dim tsh As Worksheet
Dim setting_Sh As Worksheet
Set dsh = ThisWorkbook.Sheets("uzsakymai")
Set tsh = ThisWorkbook.Sheets("lapukas")
Set setting_Sh = ThisWorkbook.Sheets("Settings")
Application.DisplayStatusBar = True
Application.StatusBar = ""
Dim i As Integer
Dim File_Name As String
For i = 2 To dsh.Range("A" & Application.Rows.Count).End(xlUp).Row
Application.StatusBar = i - 1 & "/" & dsh.Range("A" & Application.Rows.Count).End(xlUp).Row - 1
tsh.Range("D1").Value = dsh.Range("C" & i).Value
tsh.Range("A4").Value = dsh.Range("B" & i).Value
tsh.Range("B4").Value = dsh.Range("A" & i).Value & " - " & dsh.Range("E" & i).Value
tsh.Range("P4").Value = dsh.Range("D" & i).Value
File_Name = dsh.Range("A" & i).Value & "(" & dsh.Range("C" & i).Value & "-" & dsh.Range("D" & i).Value & ").pdf"
tsh.ExportAsFixedFormat xlTypePDF, setting_Sh.Range("F4").Value & "\" & File_Name
Next i
Application.StatusBar = ""
MsgBox "Done"
End Sub
But what it does is creating invoice for each item.
EXAMPLE
Any ideas how could I make it work for me as I want it to work?
---EDIT---
After ALeXceL answer, it seems to have some bugs. I changed my code to his code, and I see some progress in creating this program, but what it does, is it shows first item correctly, but all the other items are appearing starting on A24 cell. EXAMPLE
---EDIT---
IT WORKS!!!
Assuming that "uzsakymai" is "orders", the 'data sheet' (dsh) and "lapukas" is the 'template' sheet (tsh), I did these changes, added some counters, in order to the logic flows the right way:
Important: before put this code to run you MUST classify the 'orders' table (dsh, or "uzsakymai") first by Name, then, by Size (as you wish, according to the images posted)
Option Explicit
Sub Create_PDF_Files()
Dim Orders_sh As Worksheet
Dim Template_sh As Worksheet
Dim setting_Sh As Worksheet
Dim oCell As Excel.Range
Dim strKey_TheName As String
Dim lngTemplate_A As Long
Dim lngSumOfItems As Long
Dim dblSumOfValues As Double
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set Orders_sh = ThisWorkbook.Sheets("uzsakymai")
Set Template_sh = ThisWorkbook.Sheets("lapukas")
Set setting_Sh = ThisWorkbook.Sheets("Settings")
Application.DisplayStatusBar = True
Application.StatusBar = ""
Dim lngI As Long
Dim File_Name As String
'At this point, the Orders_sh worksheet should already have its fields properly sorted/ordered. (Name, then Size)
lngI = 2
Application.StatusBar = lngI - 1 & "/" & Orders_sh.Range("A11").End(xlUp).Row - 1 'a maximum of 10 items can be written here!
Set oCell = Orders_sh.Range("A" & lngI) ' the initial cell
Do
strKey_TheName = UCase(Orders_sh.Range("C" & lngI).Value)
lngSumOfItems = 0
dblSumOfValues = 0
Do
Template_sh.Range("D1").Value = Orders_sh.Range("C" & lngI).Value
lngTemplate_A = IIf(lngSumOfItems = 0, 4, Template_sh.Range("A10").End(xlUp).Offset(1, 0).Row)
Template_sh.Range("A" & lngTemplate_A).Value = Orders_sh.Range("B" & lngI).Value
Template_sh.Range("B" & lngTemplate_A).Value = Orders_sh.Range("A" & lngI).Value & " - " & Orders_sh.Range("E" & lngI).Value
Template_sh.Range("P" & lngTemplate_A).Value = Orders_sh.Range("D" & lngI).Value
lngSumOfItems = lngSumOfItems + 1
dblSumOfValues = dblSumOfValues + Orders_sh.Range("D" & lngI).Value
File_Name = lngSumOfItems & "(" & Orders_sh.Range("C" & lngI).Value & "-" & VBA.Round(dblSumOfValues, 0) & ").pdf"
lngI = lngI + 1
Set oCell = oCell.Offset(1, 0)
Loop Until strKey_TheName <> UCase(oCell.Offset(0, 2).Value)
Template_sh.ExportAsFixedFormat xlTypePDF, setting_Sh.Range("F4").Value & "\" & File_Name
Template_sh.Range("D1").Value = ""
Template_sh.Range("A4:P10").ClearContents
Loop Until Len(oCell.Value) = 0
Application.StatusBar = ""
MsgBox "Done"
End Sub
I have between 800 excels files that I need to transfer over to one sheet but before the transfer, I need to add a column ("A:A") and copy one cell value (before column added ("C1") after column ("D1")) and use column ("C:C") to get the range it would need to be pasted in column("A:A")
I have done the code already but struggling to add this on. If anyone can help that would be amazing.
Sub LoopThrough()
Dim MyFile As String, Str As String, MyDir As String
Dim sh As Worksheet, MasterRange As Range, TempWB As Workbook, TempSH As Worksheet, TempRng As Range, TempRow As Range
Dim NewMasterLine As Long
Dim StartTime As Double
Dim MinutesElapsed As String
StartTime = Timer
On Error GoTo ErrorHandler
Set sh = ThisWorkbook.Worksheets("Sheet1")
' Change address to suite
MyDir = "C:\"
MyFile = Dir(MyDir & "*.xls")
ChDir MyDir
' The following lines will put excel in a state similar to "frozen" mode. This will increase the code performance, as CPU will solely focus on performing
' the operations required by the code and not on showing the changes happening on excel
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim x As Long
x = 0
' Here starts the loop related to the files in folder
Do While MyFile <> ""
'TempWB is a Worksheet object - will be the importing worksheet. TempRng is the used range in sheet 1 of the workbook
Set TempWB = Workbooks.Open(FileName:=MyFile, UpdateLinks:=False, Password:=CalcPassword(MyFile))
Columns(1).Insert
Range("c2").Copy Range("A4:A10000")
Set TempSH = TempWB.Worksheets(1)
Set TempRng = TempSH.Range("A1:DB" & TempSH.Range("A" & TempSH.Rows.Count).End(xlUp).Row)
TempRng.Range("A:A").Insert ' This is where I tried to add in the extra column
TempRng.Range("A1").Value = TempRng.Range("D1").Value ' Tried doing this as a test but still pasted as if no changes had been made????
'NewMasterLine is the last used row (+1) of the Master Workbook (It is basically where the new rows will start to be imported)
NewMasterLine = sh.Range("A" & sh.Rows.Count).End(xlUp).Row
If NewMasterLine > 1 Then NewMasterLine = NewMasterLine + 1
'This will loop through all the rows of the range to be imported, checking the first column.
' If the value in the second column is work-xne-ams, will import the single row in the master workbook
For Each TempRow In TempRng.Rows
If Left(TempRow.Cells(1, 2).Value, 5) = "SHIFT" Or TempRow.Row < 4 Then
'If TempRow.Cells(1, 2).Value = "SHIFT--1" Or TempRow.Row < 4 Then
Set MasterRange = sh.Range("A" & NewMasterLine & ":DA" & NewMasterLine)
MasterRange.Value = TempRow.Value
NewMasterLine = NewMasterLine + 1
End If
Next
TempWB.Close savechanges:=False
MyFile = Dir()
x = x + 1
ThisWorkbook.Worksheets("PWD").Range("H2") = x
Loop
ErrorHandler:
If Err.Number <> 0 Then MsgBox "An error occurred." & vbNewLine & vbNewLine & "Last file that was attempted to be opened: " & MyFile & vbNewLine & vbNewLine & Err.Description
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation
End Sub
Function CalcPassword(FileName As String) As String
CalcPassword = ""
On Error Resume Next
Dim TheFile As String: TheFile = Split(Split(FileName, "\")(UBound(Split(FileName, "\"))), ".")(0)
Dim PWD As Range: Set PWD = ThisWorkbook.Worksheets("PWD").ListObjects("PWD").DataBodyRange
CalcPassword = WorksheetFunction.VLookup(TheFile, PWD, 5, False)
End Function
I keep getting and error message at Set MainRng = Workbooks(mainfile)
It is an object not defined error, this works in my other spreadsheet, but not in the new one.
Sub LoadData(mainfile As String, srcfile As String)
Dim DS As Worksheet
Dim Cell As Range
Dim CurrentRow As Integer, ValPos As Integer
Dim AsFoundLoc As String, AsLeftLoc As String, ValTextLoc As String
Dim SheetName As String, ValDataText As String, FileValidation As String
Dim ImportData As Variant, Multiplier As Variant, AutomationType As String
Dim AsLeftData As Variant
Dim VerifySheetName As String
Workbooks(srcfile).Activate
AutomationType = Workbooks(mainfile).Worksheets("Import Map").Range("B5").Value
SheetName = Workbooks(mainfile).Worksheets("Import Map").Range("B7").Value
ValDataText = Workbooks(mainfile).Worksheets("Import Map").Range("A10").Value
ValTextLoc = Workbooks(mainfile).Worksheets("Import Map").Range("B10").Value
'Set ValPos to 0
ValPos = 0
AsLeftData = vbNo
'Set the Verify Sheet Name
VerifySheetName = SheetName
'Change Verify Sheet Name for SureCal
'If SureCal Ask if this is As Left Data
If AutomationType = "SureCal" Then
VerifySheetName = "Cover Sheet"
AsLeftData = MsgBox("NOTE: For SureCal the you will need to Import Data for both" & Chr(13) & "the As Found and As Left Data Seperately if required" _
& Chr(13) & Chr(13) & "Are you Importing the Left Data now?", vbYesNo)
End If
'Check to see if a validation text is used
If ValDataText <> "" And ValTextLoc <> "" Then
FileValidation = Workbooks(srcfile).Worksheets(VerifySheetName).Range(ValTextLoc).Value
ValPos = InStr(1, FileValidation, ValDataText, vbTextCompare)
Else
ValPos = 1
End If
'Proceed if File Text Validated
If ValPos <> 0 Then
Application.StatusBar = "Importing Data..."
Set MainRng = Workbooks(mainfile).Worksheets("Import Map").Range("A" & DS_StartRow & ":A" & DS_LastRow)
Workbooks(mainfile).Activate
For Each Cell In MainRng
CurrentRow = Cell.Row
SheetName = Workbooks(mainfile).Worksheets("Import Map").Range("B7").Value
AsFoundLoc = Workbooks(mainfile).Worksheets("Import Map").Range("C" & CurrentRow).Value
AsLeftLoc = Workbooks(mainfile).Worksheets("Import Map").Range("D" & CurrentRow).Value
Multiplier = Workbooks(mainfile).Worksheets("Import Map").Range("E" & CurrentRow).Value
ImportData = ""
'Now add the AsFound data
If AsFoundLoc <> "" Then
ImportData = Workbooks(srcfile).Worksheets(SheetName).Range(AsFoundLoc).Value
'Call the Correct Automation Type to Format Data input
If AutomationType = "SureCal" Then ImportData = SureCalData(ImportData)
If AutomationType = "NI" Then ImportData = NIData(ImportData)
'First line of code moves data to datasheet, 2nd line of code adds it to the Repeatability column
If Not IsEmpty(ImportData) Then
If IsNumeric(ImportData) Or LCase(ImportData) = "pass" Or LCase(ImportData) = "fail" Then
If IsNumeric(ImportData) Then
ImportData = ImportData * Multiplier
End If
If AsLeftData = vbNo Then
Workbooks(mainfile).Worksheets("Datasheet").Range("I" & CurrentRow).Value = ImportData
Workbooks(mainfile).Worksheets("Import Map").Range("F" & CurrentRow).Value = ImportData
Else
Workbooks(mainfile).Worksheets("Datasheet").Range("J" & CurrentRow).Value = ImportData
End If
End If
End If
End If
'Now add the AsLeft data
'Note: As Left is skipped for SureCal Imports
If AutomationType <> "SureCal" Then
If AsLeftLoc <> "" Then
ImportData = ""
ImportData = Workbooks(srcfile).Worksheets(SheetName).Range(AsLeftLoc).Value
'Call the Correct Automation Type to Format Data input - Note: SureCal Does not get Called
'If AutomationType = "SureCal" Then ImportData = SureCalData(ImportData)
If AutomationType = "NI" Then ImportData = NIData(ImportData)
If Not IsEmpty(ImportData) Then
If IsNumeric(ImportData) Or LCase(ImportData) = "pass" Or LCase(ImportData) = "fail" Then
If IsNumeric(ImportData) Then
ImportData = ImportData * Multiplier
End If
Workbooks(mainfile).Worksheets("Datasheet").Range("J" & CurrentRow).Value = ImportData
End If
End If
End If
End If
Next Cell
'Determine Starting of Data in each the main and the source
'Workbooks(srcfile).Activate
'Workbooks(mainfile).Activate
Else
MsgBox "Validation Text ( " & ValDataText & " ) Was not Found in the " & VerifySheetName _
& " at Cell " & ValTextLoc & Chr(13) & Chr(13) & "No Data was Imported"
End If
End Sub
Error 1004 on this line:
Set MainRng = Workbooks(mainfile).Worksheets("Import Map").Range("A" & DS_StartRow & ":A" & DS_LastRow)
Means something is wrong with the parameters given to the Range call (bad arguments for Workbooks or Worksheets would throw error 9 / "subscript out of range").
.Range("A" & DS_StartRow & ":A" & DS_LastRow)
Variables DS_StartRow and DS_LastRow aren't declared or assigned anywhere in the code you posted before this instruction gets to run.
Without Option Explicit and assuming they aren't global variables defined elsewhere, looks like it's safe to assume their value is 0.
.Range("A0:A0")
...is illegal, since worksheet row addresses are 1-based. Hence, error 1004 is thrown.
One way to narrow down on the problem, is to split such instructions doing too many things, into smaller statements that do one thing:
Dim wb As Workbook
Set wb = Workbooks(mainfile)
Dim ws As Worksheet
Set ws = wb.Worksheets("Import Map")
Dim map As Range
Set map = ws.Range("A" & DS_StartRow & ":A" & DS_LastRow)
Now it's much easier to see exactly which instruction is failing.
I have some vArrays which are not clearing out. The purspose of the macro is to work on a raw data tab which has 30+ tabs, each tab holding information for a specific office, 001-New York, etc. The macro is supposed to select x number of tabs (based on a reference file), copy them and save them into a new workbook. The problem is that instead of copying and saving from the raw data file it save the reference file instead. A For...Next loop is used to determine which tabs/offices to select & copy from the raw data file. The varrays are inside the loop and contain the names of the offices. When the code encounters the vArray the varray values are not clearing out when the loop circles back around.
Example:
'For 1' reference a cell with value of "8" so it populates 8 different vArray values (offices in this case). 'For 2' has a reference number of 5 and is supposed to populate 5 vArray values. It does this correctly as I can see the 5 new values in the locals window under vArray (1) thru vArray (5), however, vArray 6 thru 8 are showing values of the previous loop instead of 'Empty'. The vArray values are not clearing out when the macro loops.
sMasterListWBName is the reference file which tells the macro which tabs to copy from the raw data file and where to move the newly created workbook. The sub is also copying, saving, and distributing the reference file instead of the raw data file for some iterations of the loop (secondary issue--I will try to refrain from splitting the thread topic).
Thanks in advance to anyone who tries to answer this question.
Option Explicit
Dim iYear As Integer, iMonth As Integer, iVer As Integer, icount As Integer, iCount2 As Integer
Dim iLetter As String, iReport As String
Dim sMonth As String, sDate As String, sVer As String, sAnswer As String
Dim sFolderName As String, sManagerInitials As String
Dim iManagerNumber As Integer, iManagerStart As Integer, iTabNumber As Integer, iTabStart As Integer
Dim sMasterListWBName As String, sConsolidatedWBName As String, sExists As String
Dim oSheet As Object, oDistList As Object
Dim vArray(300) As Variant
Dim wbDistList As Workbook
Dim wsAgentListSheet As Worksheet, wsMain As Worksheet
Dim rCell As Range, rCell2 As Range, rCellTotal As Range
Public sFINorAgent As String
Sub Agent_Distribute()
On Error Resume Next
iYear = frm_fin_rep_main_distribute.txt_year
iMonth = frm_fin_rep_main_distribute.txt_month
iVer = frm_fin_rep_main_distribute.txt_version
sMonth = Right("0" & iMonth, 2)
sDate = iYear & "." & sMonth
sVer = "V" & iVer
sAnswer = MsgBox("Is the following information correct?" & vbNewLine & vbNewLine & _
"Report - " & frm_fin_rep_main.sLetter & vbNewLine & _
"Year - " & iYear & vbNewLine & _
"Month - " & sMonth & vbNewLine & _
"Name - " & frm_fin_rep_main.sReport & vbNewLine & _
"Version - " & sVer, vbYesNo + vbInformation, "Please verify...")
If sAnswer <> vbYes Then
Exit Sub
End If
Unload frm_fin_rep_main_distribute
frm_agent.Hide
Form_Progress
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
sConsolidatedWBName = ActiveWorkbook.Name
sMasterListWBName = "Dist Master List Final.xls"
If Not IsFileOpen(sMasterListWBName) Then
Workbooks.Open FileName:= _
"W:\Addins\01 GL - Distribution\" & sMasterListWBName, Password:="password"
Workbooks(sConsolidatedWBName).Activate
End If
Set oDistList = Workbooks(sMasterListWBName).Worksheets("Agent")
With oDistList
iManagerNumber = .Range("ManNumber2") 'range value = 66
For iManagerStart = 2 To iManagerNumber '2 to 66
If .Range("A" & iManagerStart) = "x" Then
iTabNumber = .Range("E" & iManagerStart) 'E2 to E66
sFolderName = .Range("F" & iManagerStart) 'F2 to F66
sManagerInitials = .Range("G" & iManagerStart) 'G2 to G66
For iTabStart = 1 To iTabNumber
vArray(iTabStart) = .Range("G" & iManagerStart).Offset(0, iTabStart)
Next iTabStart
If iTabNumber = 1 Then
Sheets(vArray(1)).Select
Else
Sheets(vArray(1)).Select
For iTabStart = 2 To iTabNumber
Sheets(vArray(iTabStart)).Select False
Next iTabStart
End If
ActiveWindow.SelectedSheets.Copy
' *** the following code is optional, remove preceding apostrophes from the following four lines to enable password protection ***
'For Each oSheet In ActiveWorkbook.Sheets
'oSheet.Protect "password"
'oSheet.EnableSelection = xlNoSelection
'Next
ActiveWorkbook.SaveAs FileName:= _
"W:\Financials\" & iYear & "\" & sDate & "\Report to Distribute Electronically\Department Reports\" _
& sFolderName & "\Current Year Financials" & "\" & "Y" & ") " & iYear & "-" & sMonth & " Agent Report Card " & sVer & " - " & sManagerInitials & ".xls"
ActiveWorkbook.Close
End If
iPercent = iManagerStart / iManagerNumber * 95
Task_Progress (iPercent)
Next iManagerStart
End With
Workbooks(sMasterListWBName).Close False
Task_Progress (100)
Unload frm_progress
Set oDistList = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Message_Done
frm_agent.Show (vbModeless)
End Sub
I fixed it. I just added "Workbooks(sWbName).activate" at the end of the loop to make sure the focus is back on the raw data file. Now all files are saving in the correct format and location. Case closed unless someone has anything else to add. Maybe someone knows the reason the macro was losing sight of its active sheet (saving reference file instead of raw data file). Thank you.
I keep getting run-time error 1004, when trying to use Rows.Count. It usually occurs the first time I run the code below, but if I reset and run again it works.
It is failing on this line:
LastRow = Cells(Rows.Count, 4).End(xlUp).Row
Any help with getting this code to run reliably would be greatly appreciated!
The code in its entirety is as follows:
Private Sub ImportAPRData_Click()
'Declare variables for columns in "Projects" spreadsheet in Approved Reliability Projects Workbook (Excel)
Dim orgSheetCol(13) As String
orgSheetCol(0) = "$E$" 'Project Title
orgSheetCol(1) = "$D$" 'Circuit Tag
orgSheetCol(2) = "$F$" 'District
orgSheetCol(3) = "$G$" 'State
orgSheetCol(4) = "$M$" 'Date recieved
orgSheetCol(5) = "$J$" 'Planned Capital Cost
orgSheetCol(6) = "$X$" 'Actual Capital Cost
orgSheetCol(7) = "$U$" 'Capital work completed date
orgSheetCol(8) = "$K$" 'Planned O&M Cost
orgSheetCol(9) = "$Y$" 'Actual O&M Cost
orgSheetCol(10) = "$V$" 'O&M work completed date
orgSheetCol(11) = "$AD$" 'Path to RWP file
orgSheetCol(12) = "I" 'Investment Reason
'Declare variables for cell values attained from APR spreadsheet
Dim orgSheetvalues(13) As Variant
orgSheetvalues(0) = "" 'Project Title
orgSheetvalues(1) = "" 'Circuit Tag
orgSheetvalues(2) = "" 'District
orgSheetvalues(3) = "" 'State
orgSheetvalues(4) = "" 'Date recieved
orgSheetvalues(5) = "" 'Planned Capital Cost
orgSheetvalues(6) = "" 'Actual Capital Cost
orgSheetvalues(7) = "" 'Capital work completed date
orgSheetvalues(8) = "" 'Planned O&M Cost
orgSheetvalues(9) = "" 'Actual O&M Cost
orgSheetvalues(10) = "" 'O&M work completed date
orgSheetvalues(11) = "" 'RWP File Path
orgSheetvalues(12) = "" 'Investment Reason
'Declare & Set Variables for opening & working with Excel Wrokbook / worksheet (Approved Relaibility Projects/Projects)
Dim xls As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Set xls = New Excel.Application
'Delcare & set variables for loops, excel row, cell numbers, etc.
Dim rownumber As Integer
rownumber = 3
Dim rowstring As String
Dim cellstring As String
Dim i As Integer
'Declare & set variable to see if RWP already exists in table
Dim tablecheck As Integer
tablecheck = 0
'Declare variable for Capital and O&M Costs / completion dates conditions
Dim Condition1 As Boolean
Dim Condition2 As Boolean
Dim Condition3 As Boolean
Dim Condition4 As Boolean
Dim Condition5 As Boolean
Dim Condition6 As Boolean
Dim Condition7 As Boolean
Dim Condition8 As Boolean
Dim LastRow As Integer
'Open Approved Reliability Projects Workbook & set worksheet to "Projects"
xls.Visible = True
xls.UserControl = True
Set wkb = xls.Workbooks.Open("\\pacificorp.us\dfs\SLCCO\SHR02\PD\POWER\AreaSystemFiles\UT\Park_City_Office\Reliability\RWP_Goal_Tracking\Approved Reliability Projects v5.xlsm", ReadOnly:=True, UpdateLinks:=False)
Set wks = wkb.Worksheets("Projects")
'Find row # for last populated row
LastRow = Cells(Rows.Count, 4).End(xlUp).Row 'For some reason it keeps giving me an error here!!!!
'For each row in APR spreadsheet get info, then make sure all criteria are met, then check to see if it already exists in table, if not insert into table
For rownumber = 3 To LastRow
rowstring = CStr(rownumber)
'Pull information from specified row in APR Spreadsheet
For i = 0 To 12
cellstring = orgSheetCol(i) & rowstring
orgSheetvalues(i) = wks.Range(cellstring).Value
If IsError(orgSheetvalues(i)) Then
orgSheetvalues(i) = wks.Range(cellstring).Text
End If
Next i
'Check to make sure that there are planned costs and completion dates before inserting into rwpT Table
Condition1 = orgSheetvalues(5) <> "" And (orgSheetvalues(7) <> "" And orgSheetvalues(7) <> "#") And orgSheetvalues(11) Like "\\*"
Condition2 = orgSheetvalues(5) = "" And orgSheetvalues(7) = "" And orgSheetvalues(11) Like "\\*"
Condition3 = orgSheetvalues(8) <> "" And orgSheetvalues(10) <> "" And orgSheetvalues(10) <> "N/A"
Condition4 = orgSheetvalues(8) = "" And orgSheetvalues(10) = ""
Condition5 = Condition1 And Condition3
Condition6 = Condition1 And Condition4
Condition7 = Condition1 And Condition3
Condition8 = (Condition5 Or Condition6) Or Condition7
If Condition8 Then
tablecheck = DCount("PlanTitle", "rwpT", "PlanTitle = '" & orgSheetvalues(0) & "'") 'check rwp table to see if plan is already there
'If plan is not there insert into rwpT Table
If tablecheck = 0 Then
CurrentDb.Execute "INSERT INTO rwpT (PlanTitle, Circuit, OpArea, State, InvestmentReason, ApprovalDate, PlanCapitalCost, ActualCapitalCost, CapitalWorkCompDate, PlanOMCost, ActualOMCost, OMWorkCompDate, File) Values ('" & orgSheetvalues(0) & "', '" & orgSheetvalues(1) & "', '" & orgSheetvalues(2) & "', '" & orgSheetvalues(3) & "','" & orgSheetvalues(12) & "', '" & orgSheetvalues(4) & "', '" & orgSheetvalues(5) & "', '" & orgSheetvalues(6) & "', '" & orgSheetvalues(7) & "', '" & orgSheetvalues(8) & "', '" & orgSheetvalues(9) & "', '" & orgSheetvalues(10) & "','" & orgSheetvalues(11) & "')"
End If
End If
Next rownumber
'Close Approved Reliability Projects Workbook & remove all handles to it
wkb.Close False 'Close workbook. False is so that it doesn't save
Set wks = Nothing
Set wkb = Nothing
xls.Quit
Set xls = Nothing
End Sub
Change Dim LastRow As Integer to Dim LastRow As Long and it will be fine, there are too many rows to have as an integer.
In VBA it's actually good practice to always use Long instead of Integer as they are both stored as longs then the integer is converted at runtime, do a search on here for more info on it.
MS Access does not have a default Rows property (or if it does, it isn't what you want to use). You want to use Rows in its Excel sense which, if run within an Excel application would default to Application.ActiveWorkbook.ActiveSheet.Rows.
Because Access doesn't know what Rows means, it uses the property from a default instance of the Excel Application object (which is different to your xls object). The default instance doesn't have a workbook open in it, or a worksheet, so it can't determine what Application.ActiveWorkbook.ActiveSheet.Rows (or Application.ActiveWorkbook.ActiveSheet.Cells) means.
Change the line saying
LastRow = Cells(Rows.Count, 4).End(xlUp).Row
so that you fully qualify your methods/properties, i.e.
LastRow = wks.Cells(wks.Rows.Count, 4).End(xlUp).Row