Best methods to reference a user function in a macro - excel

Afternoon,
I currently have this User Function saved:
Function AlphaNumericOnly(strSource As String) As String
Dim i As Integer
Dim strResult As String
For i = 1 To Len(strSource)
Select Case Asc(Mid(strSource, i, 1))
Case 48 To 57, 65 To 90, 97 To 122: 'include 32 if you want to include space
strResult = strResult & Mid(strSource, i, 1)
End Select
Next
AlphaNumericOnly = strResult
End Function
I call this User Function in some macros that I run (checking that it is open in the macro). The issue I'm having is when I need to share a macro that references this with another user.
I could of course copy the User Function and send that along with a copy of the macro, they could then save it locally and adjust the macro to check their local copy is open. But this seems quite long winded.
Could anybody offer any suggestions? I am wondering if I could somehow embed the User Function in the macro, or store it centrally some how. Some web searching and asking around has drawn a blank on this one.
Thank you.
Please see the complete macro along with the user function at the end:
Option Explicit
Public Const csFORMULA = "=concatenate(""AGSBIS"",IF(I2=0,"""",CONCATENATE(UPPER(AlphaNumericOnly(LEFT(I2,3))),UPPER(AlphaNumericOnly(RIGHT(I2,3))))),IF(O2=0,"""",UPPER(AlphaNumericOnly(SUBSTITUTE(O2,""0"","""")))),IF(R2=0,"""",UPPER(AlphaNumericOnly(SUBSTITUTE(R2,""0"","""")))),IF(W2=0,"""",UPPER(AlphaNumericOnly(SUBSTITUTE(W2,""0"","""")))),IF(AC2=0,"""",AlphaNumericOnly(SUBSTITUTE(AC2,""0"",""""))),IF(AD2=0,"""",SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(AD2,""-"",""X""),""."",""Y""),""0"",""Z"")),IF(AF2=0,"""",SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(AF2,""-"",""X""),""."",""Y""),""0"",""Z"")),IF(AH2=0,"""",SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(AH2,""-"",""X""),""."",""Y""),""0"",""Z"")))"
Sub AgeasBIS()
Dim lr As Long
Dim cl As Range
Dim Rng As Range
Dim mssg As String
Dim WS As Worksheet
Dim SaveToDirectory As String
Dim DateFormat As String
Dim StatementName As String
Dim Organisation As String
Dim ErrorMessage As String
Dim ErrorMessageTitle As String
Dim CompleteMessage As String
Dim CompleteMessageTitle As String
Dim UserFunctionsLocation As String
Dim SaveLocation As String
DateFormat = Format(CStr(Now), "yyyy_mm_dd_hhmmss_")
ErrorMessageTitle = "Invalid Date Format"
ErrorMessage = "There are invalid date value(s) in the following cell(s). Please check these cells."
CompleteMessageTitle = "Statement Preparation"
CompleteMessage = "Statement preparation is complete. Your file has been saved and will be processed as part of the next scheduled upload."
StatementName = "age_bts"
Organisation = "BTS"
' save locations
'*location of the old user function* UserFunctionsLocation = "C:\Users\user.name\AppData\Roaming\Microsoft\AddIns\UserFunctions.xla"
SaveLocation = "S:\MI\gre_cac\statement_feeds\waiting_to_upload\"
Set WS = ActiveSheet
Application.ScreenUpdating = False
Workbooks.Open Filename:=UserFunctionsLocation
'clears any formats from the sheet
With WS
.Cells.ClearFormats
End With
'standardises all fonts
With WS.Cells.Font
.Name = "Calibri"
.Size = 10
.Bold = False
End With
With WS
'cleans all non_printable characters from the data (excluding date columns) & removes "'" & ","
'trims the insurer comments field to ensure it is a maximum of 500 characters
lr = .Range("I" & Rows.Count).End(xlUp).Row
Set Rng = Union(.Range("C2:AA" & lr), .Range("AD2:AO" & lr), .Range("AM2:AM" & lr))
For Each cl In Rng
If cl.Column = 39 Then 'column AM gets Left() truncation as well
cl = Left(WorksheetFunction.Trim(WorksheetFunction.Clean(cl.Value)), 500)
cl = WorksheetFunction.Substitute(cl.Value, "'", "")
cl = WorksheetFunction.Substitute(cl.Value, ",", "")
Else
cl = WorksheetFunction.Trim(WorksheetFunction.Clean(cl.Value))
cl = WorksheetFunction.Substitute(cl.Value, "'", "")
cl = WorksheetFunction.Substitute(cl.Value, ",", "")
End If
Next cl
'format invoice_date, effective_date & spare_date to dd/mm/yyyy
Union(.Range("AB1:AB" & lr), .Range("AC1:AC" & lr), .Range("AP1:AP" & lr)).NumberFormat = "dd/mm/yyyy"
'formats all numerical fields to "0.00"
Union(.Range("AD2:AL" & lr), .Range("AO2:AO" & lr)).NumberFormat = "0.00"
'add the statement name
Range("A2:A" & lr).FormulaR1C1 = StatementName
'add the organisation name
Range("D2:D" & lr).FormulaR1C1 = Organisation
'adds the formula to generate the unique key (from the declared constant)
Range("B2:B" & lr).Formula = csFORMULA
Range("B2:B" & lr) = Range("B2:B" & lr).Value
'auto-fit all columns
With WS
.Columns.AutoFit
End With
'checks that only date values as present in the invoice_date, effective_date & spare_date
Set Rng = Union(.Range("AB2:AB" & lr), .Range("AC2:AC" & lr), .Range("AP2:AP" & lr))
For Each cl In Rng
If Not IsDate(cl.Value) And Not IsEmpty(cl) Then _
mssg = mssg & cl.Address(0, 0) & Space(4)
Next cl
End With
'If non-date values are found display a message box showing the cell locations
If CBool(Len(mssg)) Then
MsgBox (ErrorMessage & Chr(10) & Chr(10) & _
mssg & Chr(10) & Chr(10)), vbCritical, ErrorMessageTitle
'Otherwise display a message that the statement preparation is complete
Else
MsgBox CompleteMessage, , CompleteMessageTitle
End If
'save location for the .csv
SaveToDirectory = SaveLocation
'uses the set dateformat and save lovation
WS.SaveAs SaveToDirectory & DateFormat & StatementName, xlCSV
Set Rng = Nothing
Set WS = Nothing
Application.ScreenUpdating = True
ActiveWorkbook.Close SaveChanges:=False
End Sub
Function AlphaNumericOnly(strSource As String) As String
Dim i As Integer
Dim strResult As String
For i = 1 To Len(strSource)
Select Case Asc(Mid(strSource, i, 1))
Case 48 To 57, 65 To 90, 97 To 122: 'include 32 if you want to include space
strResult = strResult & Mid(strSource, i, 1)
End Select
Next
AlphaNumericOnly = strResult
End Function

Working through the comments:
Try adding a tempValue before the Select Case
Function AlphaNumericOnly(strSource As String) As String
Dim i As Integer
Dim strResult As String
Dim tempValue As Integer
For i = 1 To Len(strSource)
tempValue = Asc(Mid(strSource, i, 1))
Select Case tempValue
Case 48 To 57, 65 To 90, 97 To 122: 'include 32 if you want to include space
strResult = strResult & Mid(strSource, i, 1)
End Select
Next
AlphaNumericOnly = strResult
End Function

Using Regular Expressions offers a shorter more efficient solution then examining each character:
Function AlphaNumericOnly(strIn) As String
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Global = True
.ignorecase = True
.Pattern = "[^\w]+"
AlphaNumericOnly = .Replace(strIn, vbNullString)
End With
End Function

Related

Concatenate strings from multiple cells WITH spaces in between - Using VBA

I'm trying to make a macro that will combine two cells, First Name and Last Name, to make Full Name.
I did find a code that does a similar thing, except with no space in between the strings. I tried to edit it to add the space but I think I'm doing it wrong. I'll paste it in in case anyone knows how to edit it to add the spaces.
Obviously if that code was not made to add spaces, please let me know if there is one that does!
Thank you!
(Here's the code for no spaces)
Sub BacsRef()
Dim rSelected As Range
Dim c As Range
Dim sArgs As String
Dim bCol As Boolean
Dim bRow As Boolean
Dim sArgSep As String
Dim sSeparator As String
Dim rOutput As Range
Dim vbAnswer As VbMsgBoxResult
Dim lTrim As Long
Dim sTitle As String
Set rOutput = ActiveCell
bCol = False
bRow = False
sSeparator = ""
sTitle = IIf(bConcat, "CONCATENATE", "Ampersand")
On Error Resume Next
Set rSelected = Application.InputBox(Prompt:= _
"Select cells to create formula", _
Title:=sTitle & " Creator", Type:=8)
On Error GoTo 0
If Not rSelected Is Nothing Then
sArgSep = IIf(bConcat, ",", "&")
If bOptions Then
vbAnswer = MsgBox("Columns Absolute? $A1", vbYesNo)
bCol = IIf(vbAnswer = vbYes, True, False)
vbAnswer = MsgBox("Rows Absolute? A$1", vbYesNo)
bRow = IIf(vbAnswer = vbYes, True, False)
sSeparator = Application.InputBox(Prompt:= _
"Type separator, leave blank if none.", _
Title:=sTitle & " separator", Type:=2)
End If
For Each c In rSelected.Cells
sArgs = sArgs & c.Address(bRow, bCol) & sArgSep
If sSeparator <> "" Then
sArgs = sArgs & Chr(34) & sSeparator & Chr(34) & sArgSep
End If
Next
lTrim = IIf(sSeparator <> "", 4 + Len(sSeparator), 1)
sArgs = Left(sArgs, Len(sArgs) - lTrim)
If bConcat Then
rOutput.Formula = "=CONCATENATE(" & sArgs & ")"
Else
rOutput.Formula = "=" & sArgs
End If
End If
End Sub
Edit: I did it myself! I added a space in the line " sSeparator = "" " within the quotation marks!

Find last row, copy data above and save as CSV

I am trying to use VBA to automatically create data set and save as CSV. I have one Dynamic_Data sheet filled with formulaes which filled when inputs from Sheetlist worksheet given. As per the formula, It can be 50 rows or 500 rows. I want to save only data that has been calculated and now have values in it. But I am not getting last row value and whole worksheet have been saved which also have lot of blank rows or rows with zero value after actual data.
Please help correcting the script.
Here is the code I used.
Sub CompileBPData()
Dim s As String
Dim sname As String
Dim StartName As String
Dim EndName As String
Dim MidName As String
Dim StartNum As String
Dim EndNum As String
Dim CoverNum1 As String
Dim CoverNum2 As String
Dim Cover As String
Dim IntMax As String
Dim GetNewSuffix As String
Dim Job As String
Dim Book As String
Dim EA As String
Dim Lrow As Long
On Error Resume Next
GetNewSuffix = " ("
IntMax = ") "
StartName = "Book "
EndName = "Job_"
MidName = "-"
Sheets("Sheetlist").Select
' Open dialouge box for selecting header
Job = InputBox("Enter Job Number")
If Job = "" Then
Exit Sub
End If
s = InputBox("Enter Next Book Number")
If s = "" Then
Exit Sub
End If
Range("D2").Value = s
Book = InputBox("How many Books in One Column")
If Book = "" Then
Exit Sub
End If
Range("H3").Value = Book
EA = InputBox("EA Code & Name Please")
If EA = "" Then
Exit Sub
End If
Range("I8").Value = EA
'******Finding Last row with no value*********
With wsInpt.Columns("E").SpecialCells(Type:=xlCellTypeBlanks)
Lrow = .Cells(.Cells.Count).Row
End With
'Lrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'**********Select Data Sheet and create Paper Data *********
Sheets("Sheetlist").Select
Range("E2").Select
StartNum = Range("E2")
EndNum = Range("E7")
CoverNum1 = Range("D2")
CoverNum2 = Range("E9")
Cover = Range("I2")
Sheets("Dynamic_Data").Select
ActiveWorkbook.SaveAs Filename:=EA & MidName & StartName & CoverNum1 & MidName & CoverNum2 & GetNewSuffix & "G" & StartNum & MidName & "G" & EndNum & IntMax & Cover & " " & StartName & "_" & EndName & Job, FileFormat:=xlCSV, CreateBackup:=False
ActiveSheet.Name = "Dynamic_Data"
Sheets("Sheetlist").Select
Range("D2").Select
End Sub
Hope this could help you.
Sub CompileBPData()
Dim s As String
Dim sname As String
Dim StartName As String
Dim EndName As String
Dim MidName As String
Dim StartNum As String
Dim EndNum As String
Dim CoverNum1 As String
Dim CoverNum2 As String
Dim Cover As String
Dim IntMax As String
Dim GetNewSuffix As String
Dim Job As String
Dim Book As String
Dim EA As String
Dim Lrow As Long
On Error Resume Next
GetNewSuffix = " ("
IntMax = ") "
StartName = "Book "
EndName = "Job_"
MidName = "-"
Sheets("Sheetlist").Select
' Open dialouge box for selecting header
Job = InputBox("Enter Job Number")
If Job = "" Then
Exit Sub
End If
s = InputBox("Enter Next Book Number")
If s = "" Then
Exit Sub
End If
Range("D2").Value = s
Book = InputBox("How many Books in One Column")
If Book = "" Then
Exit Sub
End If
Range("H3").Value = Book
EA = InputBox("EA Code & Name Please")
If EA = "" Then
Exit Sub
End If
Range("I8").Value = EA
'******Finding Last row with no value*********
With wsInpt.Columns("E").SpecialCells(Type:=xlCellTypeBlanks)
Lrow = .Cells(.Cells.Count).Row
End With
'Lrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'**********Select Data Sheet and create Paper Data *********
Sheets("Sheetlist").Select
Range("E2").Select
StartNum = Range("E2")
EndNum = Range("E7")
CoverNum1 = Range("D2")
CoverNum2 = Range("E9")
Cover = Range("I2")
'------------------ BEGIN OF EDITED PART --------------------------------
'Loop Until Calculation is Done
Do
DoEvents
Loop While Not Application.CalculationState = xlDone
'Find Last ROW
Dim LastRow As Double
LastRow = 60001 ' <-- NOTE!: YOU MUST PUT HERE MAX ROWS NUMBER ))
Do
LastRow = LastRow - 1
Loop Until Worksheets("Dynamic_Data").Range("A" & LastRow).Value <> 0
MsgBox "LastRow= " & LastRow
'Copy the Range of Data
Worksheets("Dynamic_Data").Range("A1:AB" & LastRow).Copy
'Save the CSV File
Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT
Set tempWB = Application.Workbooks.Add(1)
With tempWB
.Sheets(1).Range("A1").PasteSpecial xlPasteValues
.SaveAs Filename:=EA & MidName & StartName & CoverNum1 & MidName & CoverNum2 & GetNewSuffix & "G" & StartNum & MidName & "G" & EndNum & IntMax & Cover & " " & StartName & "_" & EndName & Job, FileFormat:=xlCSV, CreateBackup:=False
.Close
End With
Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS
'------------------ END OF EDITED PART --------------------------------
ActiveSheet.Name = "Dynamic_Data"
Sheets("Sheetlist").Select
Range("D2").Select
End Sub

How can all characters from excel file be counted?

I was using the script which I found here : https://excelribbon.tips.net/T008349_Counting_All_Characters.html
It is working as expected however when there are some other objects like pictures, the script returns me the error 438"Object Doesn't Support This Property or Method".
When I deleted the pictures the script was working well again.
Is there an option to put in the script something like "ignore pictures"? Or is there any better type of script to achieve this? I am not good at all at VBA, all help will be much appreciated.
Here's a simplified approach that may work out a bit better. I think being explicit which Shape Types you want to count is going to be a cleaner way of going about this.
Option Explicit
Private Function GetCharacterCount() As Long
Dim wks As Worksheet
Dim rng As Range
Dim cell As Range
Dim shp As Shape
For Each wks In ThisWorkbook.Worksheets
For Each shp In wks.Shapes
'I'd only add the controls I care about here, take a look at the Shape Type options
If shp.Type = msoTextBox Then GetCharacterCount = GetCharacterCount + shp.TextFrame.Characters.Count
Next
On Error Resume Next
Set rng = Union(wks.UsedRange.SpecialCells(xlCellTypeConstants), wks.UsedRange.SpecialCells(xlCellTypeFormulas))
On Error GoTo 0
If not rng Is Nothing Then
For Each cell In rng
GetCharacterCount = GetCharacterCount + Len(cell.Value)
Next
end if
Next
End Function
Sub CountCharacters()
Debug.Print GetCharacterCount()
End Sub
It looks like you can add an if-check like the one here (VBA Code to exclude images png and gif when saving attachments for "PNG" and "GIF".).
You just have to change the if-check to check for the picture type you're using "JPG" or "JPEG"? Simply match the extension to the if-check by replacing "PNG" or "GIF" with your extension in CAPS.
Add the if-check right above where the error is occurring or better yet, add it above the scope of where the error is occurring.
I took the script from your link and modified it. Now it works.
It's far from perfect (there're some cases where it can still crash), but now it supports handling Shapes with no .TextFrame property:
Sub CountCharacters()
Dim wks As Worksheet
Dim rng As Range
Dim rCell As Range
Dim shp As Shape
Dim bPossibleError As Boolean
Dim bSkipMe As Boolean
Dim lTotal As Long
Dim lTotal2 As Long
Dim lConstants As Long
Dim lFormulas As Long
Dim lFormulaValues As Long
Dim lTxtBox As Long
Dim sMsg As String
On Error GoTo ErrHandler
Application.ScreenUpdating = False
lTotal = 0
lTotal2 = 0
lConstants = 0
lFormulas = 0
lFormulaValues = 0
lTxtBox = 0
bPossibleError = False
bSkipMe = False
sMsg = ""
For Each wks In ActiveWorkbook.Worksheets
' Count characters in text boxes
For Each shp In wks.Shapes
If TypeName(shp) <> "GroupObject" Then
On Error GoTo nextShape
lTxtBox = lTxtBox + shp.TextFrame.Characters.Count
End If
nextShape:
Next shp
On Error GoTo ErrHandler
' Count characters in cells containing constants
bPossibleError = True
Set rng = wks.UsedRange.SpecialCells(xlCellTypeConstants)
If bSkipMe Then
bSkipMe = False
Else
For Each rCell In rng
lConstants = lConstants + Len(rCell.Value)
Next rCell
End If
' Count characters in cells containing formulas
bPossibleError = True
Set rng = wks.UsedRange.SpecialCells(xlCellTypeFormulas)
If bSkipMe Then
bSkipMe = False
Else
For Each rCell In rng
lFormulaValues = lFormulaValues + Len(rCell.Value)
lFormulas = lFormulas + Len(rCell.Formula)
Next rCell
End If
Next wks
sMsg = Format(lTxtBox, "#,##0") & _
" Characters in text boxes" & vbCrLf
sMsg = sMsg & Format(lConstants, "#,##0") & _
" Characters in constants" & vbCrLf & vbCrLf
lTotal = lTxtBox + lConstants
sMsg = sMsg & Format(lTotal, "#,##0") & _
" Total characters (as constants)" & vbCrLf & vbCrLf
sMsg = sMsg & Format(lFormulaValues, "#,##0") & _
" Characters in formulas (as values)" & vbCrLf
sMsg = sMsg & Format(lFormulas, "#,##0") & _
" Characters in formulas (as formulas)" & vbCrLf & vbCrLf
lTotal2 = lTotal + lFormulas
lTotal = lTotal + lFormulaValues
sMsg = sMsg & Format(lTotal, "#,##0") & _
" Total characters (with formulas as values)" & vbCrLf
sMsg = sMsg & Format(lTotal2, "#,##0") & _
" Total characters (with formulas as formulas)"
MsgBox Prompt:=sMsg, Title:="Character count"
ExitHandler:
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
If bPossibleError And Err.Number = 1004 Then
bPossibleError = False
bSkipMe = True
Resume Next
Else
MsgBox Err.Number & ": " & Err.Description
Resume ExitHandler
End If
End Sub
You could try:
Option Explicit
Sub test()
Dim NoOfChar As Long
Dim rng As Range, cell As Range
NoOfChar = 0
For Each cell In ThisWorkbook.Worksheets("Sheet1").UsedRange '<- Loop all cell in sheet1 used range
NoOfChar = NoOfChar + Len(cell.Value) '<- Add cell len to NoOfChar
Next cell
Debug.Print NoOfChar
End Sub

Importing Cell values to Sheet from another workbook

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.

Output an array of data collected from a file to a specific sheet in Master workbook

The following code opens selected files, one at a time; if a file contains specific text string in B11 (there are four variation: LS2A, LS1PRA, LS1A and LSM12), specified data from Sheet(1) of each file is copied into an array. The search is performed by function “SearchFor” that is called in the main routine.
The array ArrCopy is filled with data from each file and should output into one of the four sheets in Master Workbook(SABI, SABII,LSM or LPRI&II). The output sheet is determined by the text string in B11 of each file.
I can’t get data to output to Master workbook for some reason. I've tried Debug.Print each array item after it's filled and I can see that the array is filled with correct data but I can't get the values to tranfer to the master workbook. The code runs but nothing is outputed on the worksheet.
Please suggest how to make this work. Thanks
Option Explicit
Function SearchFor(output As Worksheet)
Dim rowsCount As Long
Dim NCBead1 As Long, NCBead2 As Long, PCBead1 As Long, PCBead2 As Long
Dim IniString As String, IniVar As String
Dim rngCell As Range, rngCell2 As Range
Dim ArrCopy(1 To 9) As Variant
Dim LastRow As Long
Dim aCell As Range
LastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
'extract initial after last underscore
IniString = ActiveWorkbook.Sheets(1).Range("B6").Value
IniVar = Right(IniString, Len(IniString) - InStrRev(IniString, "_", , 1))
Debug.Print IniVar
'Debug.Print "LastRow = " & LastRow
Set aCell = ActiveSheet.Range("B1:B" & LastRow).Find(What:="Trimmed Mean", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'Debug.Print "Trimmed Mean can be found in Row # " & aCell.Row
'wb.Sheets(1).Select
For Each rngCell In ActiveSheet.Range("B" & aCell.Row & ":B" & LastRow)
If InStr(rngCell, "NC") > 0 Then
Debug.Print rngCell.Row
NCBead1 = rngCell.Offset(0, 1).Value
NCBead2 = rngCell.Offset(0, 2).Value
'End If
Exit For
End If
Next rngCell
For Each rngCell2 In ActiveSheet.Range("B" & aCell.Row & ":B" & LastRow)
If InStr(rngCell2, "PC") > 0 Then
Debug.Print rngCell2.Row
PCBead1 = rngCell2.Offset(0, 1).Value
PCBead2 = rngCell2.Offset(0, 2).Value
'End If
Exit For
End If
Next rngCell2
'Next searched
Debug.Print NCBead2
ArrCopy(1) = ActiveSheet.Range("B3").Value
ArrCopy(2) = IniVar
ArrCopy(3) = NCBead1
ArrCopy(4) = NCBead2
ArrCopy(5) = PCBead1
ArrCopy(6) = PCBead2
ArrCopy(7) = ActiveSheet.Range("B6").Value
ArrCopy(8) = NCBead1
ArrCopy(9) = NCBead1
' one row spanning several columns
Debug.Print "ArrCopy" & ArrCopy(1)
Debug.Print "ArrCopy" & ArrCopy(2)
Debug.Print "ArrCopy" & ArrCopy(3)
Dim Destination As Range
Set Destination = output.Range("A" & output.Range("A" & Rows.Count).End(xlUp).Row + 1)
Set Destination = Destination.Resize(1, UBound(ArrCopy))
Destination.Value = ArrCopy
End Function
Sub openselectedfiles()
Dim SaveDriveDir As String, MyPath As String, FnameInLoop As String
Dim mybook As Workbook, thisWb As Workbook
Dim N As Long, LstUnderSc As Long, ExtPer As Long, Varin As Long
Dim Fname As Variant, ArrCopy(1 To 9) As Variant
Dim output As Worksheet
Dim inLS2A As Boolean, inLS1PRA As Boolean, inLS1A As Boolean, inLSM12 As Boolean
Set thisWb = ThisWorkbook
' Save the current directory.
SaveDriveDir = CurDir
' Set the path to the folder that you want to open.
MyPath = Application.DefaultFilePath
' Change drive/directory to MyPath.
ChDrive MyPath
ChDir MyPath
' Open GetOpenFilename with the file filters.
Fname = Application.GetOpenFilename( _
FileFilter:="CSV Files (*.csv),*.csv", _
Title:="Select a file or files", _
MultiSelect:=True)
' Perform some action with the files you selected.
If IsArray(Fname) Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For N = LBound(Fname) To UBound(Fname)
' Get only the file name and test to see if it is open.
FnameInLoop = Right(Fname(N), Len(Fname(N)) - InStrRev(Fname(N), Application.PathSeparator, , 1))
If bIsBookOpen(FnameInLoop) = False Then
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(Fname(N))
On Error GoTo 0
If Not mybook Is Nothing Then
mybook.Sheets(1).Select
With ActiveSheet.Range("B11")
inLS2A = InStr(1, .Value, "LS2A", 1) > 0
inLS1PRA = InStr(1, .Value, "LS1PRA", 1) > 0
inLS1A = InStr(1, .Value, "LS1A", 1) > 0
inLSM12 = InStr(1, .Value, "LSM12", 1) > 0
End With
If inLS2A Then
Set output = thisWb.Sheets("SABII")
SearchFor output
ElseIf inLS1PRA Then
Set output = thisWb.Sheets("LPRI&II")
SearchFor output
ElseIf inLS1A Then
Set output = thisWb.Sheets("sabI")
SearchFor output
ElseIf inLSM12 Then
Set output = thisWb.Sheets("LSM")
SearchFor output
End If
'End If
mybook.Close SaveChanges:=False
Set mybook = Nothing
End If
Else
MsgBox "We skipped this file : " & Fname(N) & " because it is already open."
End If
Next N
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End If
' Change drive/directory back to SaveDriveDir.
ChDrive SaveDriveDir
ChDir SaveDriveDir
End Sub
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