Value error on CountIf looping through closed workbooks - excel

I want a function that loops through closed workbooks having some parameters given from cells of onother workbook. The aim is to count the number of presence of people in some locations considering a month.
Option Explicit
Public Function ContMonth(colleague As Range, location As Range, month As Range) As Long
Dim nameMonth As String
Dim nameLocation As String
Dim nameColleague As String
Dim rangeLocation As String
Dim stringMonth As String
Dim file As Variant
Dim count As Integer
nameMonth = month
nameLocation = location
nameColleague = colleague
Select Case True
Case nameLocation = "ponte milvio"
rangeLocation = "$A$2:$B$2"
Case Else
rangeLocation = "null"
End Select
Select Case True
Case nameMonth = "January"
stringMonth = "-01-2022"
Case Else
stringMonth = "null"
End Select
file = Dir("C:\Users\sbalo\Desktop\Test\*.xlsx")
While (file <> "")
Do While InStr(file, stringMonth) > 0
count = count + Application.CountIf("C:\Users\sbalo\Desktop\Test\" & "[" & file & "]" & "Sheet1" & "'" & "!" & rangeLocation, nameColleague)
file = Dir()
Loop
Wend
End Function
Sub Test()
Dim counter As Long
Dim name As Range
Dim location As Range
Dim month As Range
Set name = Range("A3")
Set location = Range("B2")
Set month = Range("B1")
counter = ContMonth(name, location, month)
End Sub
this time giving me type mismatching on line:
count = count + Application.CountIf("C:\Users\sbalo\Desktop\Test\" & "[" & file &
"]" & "Sheet1" & "'" & "!" & rangeLocation, nameColleague)

Related

VBA activeworbook.close 1004 runtime error, missing folder path

Sub LoopThroughFolder()
Dim table As Range
Dim FSO
Dim month As String
Dim year As String
Dim FileName As String
Dim OldFileName As String
Dim MainPath As String
Dim ClientPath As String
Dim FullPath As String
Dim FileToOpen As Workbook
Dim Text As String
Application.ScreenUpdating = False
Set wb = ThisWorkbook
Set ws = wb.Worksheets("FileName")
month = ws.Range("E8")
year = ws.Range("F8")
OldFileName = ws.Range("R5")
MainPath = "C:\Document\documents\CPREIF_daily_test\"
ClientPath = MainPath & year & "\" & month & " - " & year & "\"
Set table = Range("B8", Range("B8").End(xlToRight).End(xlDown))
For Each Row In table.Rows
Text = Row.Cells(1, 1)
FileName = Row.Cells(1, 7)
Set FileToOpen = Workbooks.Open(ClientPath & OldFileName, UpdateLinks:=0)
Range("B4").ClearContents
Range("B4") = Text
Range("B4").NumberFormat = "dddd mmmm d" & ", " & "yyyy"
ActiveWorkbook.Close True, ClientPath & FileName
Next Row
MsgBox "Client Files Turned"
End Sub
Hey All. I wrote VBA to loop through each row of a table, renaming the workbook and changing the date within a cell, based off each row in a table. When I run the code within VBA editor, the code works. When I create a button and assign the macro to the button, I receive a runtime error. The code that breaks is:
ActiveWorkbook.Close True, ClientPath & FileName
Thanks!

VBA to copy pdf files from one location to another with progress bar

I have an imported CSV which will always put part numbers into Column B, the part drawing PDF is located in a central location.
I am trying to copy each drawing from one folder location to another, this part i have been successful with, however some of the files can have up to 3000 lines which means the copy sub can take some time to complete and may seem like excel is not functioning.
I have created a progress bar from some helpful tutorial, but i am struggling to combine them.
I understand the progress bar needs to calculate something in order to move the slider so i included a sub to count the number of unique entries in column B ( this would be the number of drawing which need copied ) The figure can then be used to create a percentage of completion?
Sub start()
UserForm1.Show
End Sub
Sub code()
Dim i As Integer, j As Integer, pctCompl As Single
'Sheet1.Cells.Clear
For i = 1 To 100
For j = 1 To 1000
Cells(i, 1).Value = j
Next j
pctCompl = i
progress pctCompl
Next i
End Sub
Sub progress(pctCompl As Single)
UserForm1.Text.Caption = pctCompl & "% Completed"
UserForm1.Bar.Width = pctCompl * 2
UserForm1.Caption = ListCount & "Files"
DoEvents
End Sub
Sub CountUniqueValues()
Dim LstRw As Long, Rng As Range, List As Object, ListCount As Long
LstRw = Cells(Rows.Count, "B").End(xlUp).Row
Set List = CreateObject("Scripting.Dictionary")
For Each Rng In Range("B2:B" & LstRw)
If Not List.Exists(Rng.Value) Then List.Add Rng.Value, Nothing
Next
ListCount = List.Count
End Sub
Sub PDFcopy()
Dim R As Range
Dim SourcePath As String, DestPath As String, FName As String
'Setup source and dest path (Note: must have a trailing backslash!)
SourcePath = "G:\test-copyfrom\" 'choose directory to copy from
DestPath = "C:\test-copyto\" 'choose directory to copy to
'Visit each used cell in column B
For Each R In Range("B1", Range("B" & Rows.Count).End(xlUp))
'Search the file with the file mask from the cell (Note: can contain wildcards like *.xls)
FName = Dir(SourcePath & R.Value & ".pdf")
'Loop while files found
Do While FName <> ""
'Copy the file
FileCopy SourcePath & FName, DestPath & FName
'Search the next file
FName = Dir()
Loop
Next
MsgBox ("files copied")
Here's how I code my progress bar
Sub progress(percentComplete As Single)
ProgressBar.Text.Caption = percentComplete & "% Completed"
ProgressBar.Bar.Width = percentComplete * 2
DoEvents
End Sub
And in my sub that does stuff:
'Update ProgressBar at certain points in the code
percentComplete = 11
progress percentComplete
Or
For each cell in Range("A1:A" & LRow)
'Do stuff
'Update ProgressBar in a loop
percentComplete = 11 + Int(cell.Row / LRow * 60) 'where 11 is the starting value, and 60 the percentage to be added
progress percentComplete
Next cell
This is to support my comment about using the progress bar
Dim f As UserForm1
Sub SetUpAProgressBar()
Set f = New UserForm1
f.Show vbModeless
f.ProgressBar1.Min = 0
f.ProgressBar1.Max = Range("a" & Rows.Count).End(xlUp).Row
f.ProgressBar1.Value = 0
End Sub
Sub IncrementProgressBar()
f.ProgressBar1.Value = f.ProgressBar1.Value + 1
End Sub
you need to add some sort of reference to your current row number in PDFcopy() sub. then count the total amount of loops to be completed. and finally, work out the percentage to pass to the progress bar!
Sub PDFcopy()
Dim R As Range
Dim I as long
Dim Total as long
Dim SourcePath As String, DestPath As String, FName As String
'Setup source and dest path (Note: must have a trailing backslash!)
SourcePath = "G:\test-copyfrom\" 'choose directory to copy from
DestPath = "C:\test-copyto\" 'choose directory to copy to
'Visit each used cell in column B
I = 0
Total = Range("B" & Rows.Count).End(xlUp)
For Each R In Range("B1", Range("B" & Rows.Count).End(xlUp))
'Search the file with the file mask from the cell (Note: can contain wildcards like *.xls)
FName = Dir(SourcePath & R.Value & ".pdf")
'Loop while files found
Do While FName <> ""
'Copy the file
FileCopy SourcePath & FName, DestPath & FName
'Search the next file
FName = Dir()
Loop
I = I + 1
call progress(I/(total/100))
Next
MsgBox ("files copied")

Rows.Count generates runtime error 1004

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

Run time error type 13 type mismatch when copying formula result that is an Error

The macro opens-copies-closes from an external file back to the master file. Issue arises from copying from ONE particular file.
Attached is the code and ** to indicate where the error occurs.
Sub UpdateDate_Click()
Dim readLastCell As Long
Dim readLastCellNameSheet As Long
Dim billNumber
Dim SheetName As String
Dim billNumberNamesheet As Long
Dim ExecutiveWorkBookPath As String
Dim excelFilePath
Dim ExecutiveWorkBook As Workbook
Dim MainTemplate As String
MainTemplate = ThisWorkbook.Name
'ChDir Defaulth path
excelFilePath = Application.ActiveWorkbook.Path + "\"
Application.EnableEvents = False
strFilename = Dir(excelFilePath & "\*xlsm")
Do While strFilename <> ""
'Set variable equal to opened workbook
If InStr(strFilename, "Executive") > 0 Then
Set ExecutiveWorkBook = Workbooks.Open(excelFilePath & strFilename, ReadOnly:=True)
ExecutiveWorkBook.Worksheets("Summary").Unprotect "12345+"
ExecutiveWorkBook.Worksheets("Summary").Range("A1:Q220000").Locked = False
readLastCell = ThisWorkbook.Sheets("Master").Cells(Rows.Count, 1).End(xlUp).Row
readLastCellNameSheet = ExecutiveWorkBook.Sheets("Summary").Cells(Rows.Count, 1).End(xlUp).Row
For x = 4 To readLastCell
cell = "A" & x
billNumber = ThisWorkbook.Worksheets("Master").Range(cell).Value
If Len(billNumber) = 0 Then Exit For
For N = 4 To readLastCellNameSheet
cell = "A" & N
'**
billNumberNamesheet = ExecutiveWorkBook.Worksheets("Summary").Range(cell).Value
If Len(billNumberNamesheet) = 0 Then Exit For
If billNumberNamesheet = billNumber Then
cell = "R" & N & ":" & "AX" & N
copycell = "R" & x & ":" & "AX" & x
ExecutiveWorkBook.Worksheets("Summary").Range(cell).Copy
ThisWorkbook.Worksheets("Master").Range(copycell).PasteSpecial Paste:=xlPasteAll
End If
Next N
Next x
My code is supposed to copy an entire line (one out of 20 columns has formula) into another workbook. So the error popped up because there was a formula that equates to an error (#N/A),(#Error)?
I need to copy regardless if the formula equates to an error. The formatting in the master workbook will correct that error.

Merge 2 Excel files with different columns, using a user form to select files and then column mapping

I need to merge two Excel files, but only certain columns from each. I need to use a userform to select the two files to merge and then also use column mapping to select which columns from each sheet need appear where in the new output sheet.
So far I have this.
Private Sub AddFilesButton_Click()
Dim arrFiles As Variant
On Error GoTo ErrMsg
'Let the user choose the files they want to merge
#If Mac Then
arrFiles = Select_File_Or_Files_Mac()
#Else
arrFiles = Application.GetOpenFilename("Excel Files (*.xls; *.xlsx), *.xls;*.xlsx", 1, "Choose Excel Files", "Select", True)
#End If
If IsNull(arrFiles) Or UBound(arrFiles) = -1 Then
MsgBox "Please choose at least one Excel file"
Else
For Each file In arrFiles
FilesListBox.AddItem file
Next file
MergeButton.Enabled = True
End If
ErrMsg:
If Err.Number <> 0 Then
MsgBox "There was an error. Please try again. [" & Err.Description & "]"
End If
End Sub
Private Sub CancelButton_Click()
Unload Me
End Sub
Private Sub MergeButton_Click()
Dim fileName As Variant
Dim wb As Workbook
Dim s As Sheet1
Dim thisSheet As Sheet1
Dim lastUsedRow As Range
Dim columnMap As Collection
Dim filePath As Variant
Dim dataRange As Range
Dim insertAtRowNum As Integer
Dim outColName As String
Dim colName As String
Dim fromRange As String
Dim fromRangeToCopy As Range
Dim toRange As String
On Error GoTo ErrMsg
Application.ScreenUpdating = False
Set thisSheet = ThisWorkbook.ActiveSheet
For i = 0 To FilesListBox.ListCount - 1
fileName = FilesListBox.List(i, 0)
'Get the map of columns for this file
Set columnMap = MapColumns(fileName)
'Open the spreadsheet in ReadOnly mode
Set wb = Application.Workbooks.Open(fileName, ReadOnly:=True)
For Each sourceSheet In wb.Sheets
'Get the used range (i.e. cells with data) from the opened spreadsheet
If firstRowHeaders And i > 0 Then 'Only include headers from the first spreadsheet
Dim mr As Integer
mr = wb.ActiveSheet.UsedRange.Rows.Count
Set dataRange = wb.ActiveSheet.UsedRange.Offset(1, 0).Resize(mr - 1)
Else
Set dataRange = wb.ActiveSheet.UsedRange
End If
For Each col In dataRange.Columns
'Get corresponding output column. Empty string means no mapping
colName = GetColName(col.Column)
outColName = GetOutputColumn(columnMap, colName)
If outColName <> "" Then
fromRange = colName & 1 & ":" & colName & dataRange.Rows.Count
Set fromRangeToCopy = dataRange.Range(fromRange)
fromRangeToCopy.Copy
toRange = outColName & insertAtRowNum & ":" & outColName & (insertAtRowNum + fromRangeToCopy.Rows.Count - 1)
thisSheet.Range(toRange).PasteSpecial
End If
Next col
insertAtRowNum = insertAtRowNum + dataRange.Rows.Count
Next sourceSheet
Application.CutCopyMode = False
Next i
ThisWorkbook.Save
Set wb = Nothing
#If Mac Then
'Do nothing. Closing workbooks fails on Mac for some reason
#Else
'Close the workbooks except this one
Dim file As String
For i = 0 To FilesListBox.ListCount - 1
file = FilesListBox.List(i, 0)
file = Right(file, Len(file) - InStrRev(file, Application.PathSeparator, , 1))
Workbooks(file).Close SaveChanges:=False
Next i
#End If
Application.ScreenUpdating = True
Unload Me
ErrMsg:
If Err.Number <> 0 Then
MsgBox "There was an error. Please try again. [" & Err.Description & "]"
End If
End Sub
Function MapColumns(fileName As Variant) As Object
Dim colMap As New Collection
Select Case fileName
Case "ExcelFile1.xlsx"
colMap.Add Key:="C", Item:="A"
colMap.Add Key:="D", Item:="B"
colMap.Add Key:="E", Item:="C"
colMap.Add Key:="I", Item:="D"
Case "ExcelFile2.xlsx"
colMap.Add Key:="B", Item:="F"
colMap.Add Key:="J", Item:="G"
colMap.Add Key:="H", Item:="H"
colMap.Add Key:="C", Item:="I"
End Select
Set MapColumns = colMap
End Function
Function GetOutputColumn(columnMap As Collection, col As String) As String
Dim outCol As String
outCol = ""
If columnMap.Count > 0 Then
outCol = columnMap.Item(col)
End If
GetOutputColumn = outCol
End Function
'From: http://www.mrexcel.com/forum/excel-questions/16444-getting-column-name-given-column-number.html
Function GetColName(ColumnNumber)
FuncRange = Cells(1, ColumnNumber).AddressLocal(False, False) 'Creates Range (defaults Row to 1) and retuns Range in xlA1 format
FuncColLength = Len(FuncRange) 'finds length of range reference
GetColName = Left(FuncRange, FuncColLength - 1) 'row always "1" therefore take 1 away from string length and you are left with column ref
End Function
'From: http://msdn.microsoft.com/en-us/library/office/hh710200%28v=office.14%29.aspx#odc_xl4_ta_ProgrammaticallySelectFileforMac_DifferencesWindowsandMac
Function Select_File_Or_Files_Mac() As Variant
Dim MyPath As String
Dim MyScript As String
Dim MyFiles As String
Dim MySplit As Variant
Dim N As Long
Dim Fname As String
Dim mybook As Workbook
On Error Resume Next
MyPath = MacScript("return (path to documents folder) as String")
'Or use MyPath = "Macintosh HD:Users:Ron:Desktop:TestFolder:"
' In the following statement, change true to false in the line "multiple
' selections allowed true" if you do not want to be able to select more
' than one file. Additionally, if you want to filter for multiple files, change
' {""com.microsoft.Excel.xls""} to
' {""com.microsoft.excel.xls"",""public.comma-separated-values-text""}
' if you want to filter on xls and csv files, for example.
MyScript = _
"set applescript's text item delimiters to "","" " & vbNewLine & _
"set theFiles to (choose file of type " & _
" {""com.microsoft.Excel.xls"",""org.openxmlformats.spreadsheetml.sheet""} " & _
"with prompt ""Please select a file or files"" default location alias """ & _
MyPath & """ multiple selections allowed true) as string" & vbNewLine & _
"set applescript's text item delimiters to """" " & vbNewLine & _
"return theFiles"
MyFiles = MacScript(MyScript)
On Error GoTo 0
MySplit = False 'Assume no files = cancel
If MyFiles <> "" Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
MySplit = Split(MyFiles, ",")
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End If
Select_File_Or_Files_Mac = MySplit
End Function
Function bIsBookOpen(ByRef szBookName As String) As Boolean
' Contributed by Rob Bovey
On Error Resume Next
bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function

Resources