0

I want to call a vba function from vbscript which has a parameter, I Know how to call a parameterized sub but having issue with function

Here is what I have tried, I tried the code here Calling vba function(with parameters) from vbscript and show the result , but this also didn't work, it gave an error as expected end of statement

Set xlObj = CreateObject("Excel.Application")
Set objWorkbook = xlObj.Workbooks.Open("E:\Headers.xlsm")

xlObj.Application.Visible = False
xlObj.Workbooks.Add

Dim result
result  = xlObj.Application.Run("Headers.xlsm!Headers",filename)

xlFile.Close True
xlObj.Quit

this my vba function

Function Headers(filename As String) As String

Application.ScreenUpdating = False

Dim myWb As Workbook
Dim i As Integer

Dim flag As Boolean
Set myWb = Workbooks.Open(filename:=filename)

Dim arr

arr = Array("col1","col2")

For i = 1 To 2
    If Cells(1, i).Value = arr(i - 1) Then
         Headers = "True"
    Else
         Headers = "False , Not Found Header " & arr(i - 1)
         Exit Function
End If
Next

myWb.Close

End Function
2
  • 2
    Shouldn't xlObj.Application.Run be xlObj.Run? xlObj is already the application. Did you manage to find out in which line the error occurs? And what is filename in your VBScript? it is not defined and empty. • Note that if you Exit Function the workbook does not get closed because myWb.Close is never reached (it cancels the function immediately at this point of the code). Instead use Exit For to just get out of the loop and still close the workbook. Commented Oct 21, 2019 at 6:34
  • xlObj.Run file name hardcoded worked , will try with dynamci Commented Oct 21, 2019 at 6:43

1 Answer 1

2
  1. In your VBScript xlObj is set to be an application Set xlObj = CreateObject("Excel.Application"). That means xlObj.Application should be xlObj only.

  2. In your VBScript Filename is not declared nor set to a value therefore it is empty. You need to define value to it.

    Set xlObj = CreateObject("Excel.Application")
    Set objWorkbook = xlObj.Workbooks.Open("E:\Headers.xlsm")
    
    xlObj.Visible = False
    xlObj.Workbooks.Add
    
    Dim Filename 'declare filename and set a value to it
    Filename = "E:\YourPath\Yourfile.xlsx"        
    
    Dim Result
    Result = xlObj.Run("Headers.xlsm!Headers", Filename)
    
    xlFile.Close True
    xlObj.Quit
    
  3. In your function you use Exit Function. This will stop the code immediately at this point, which means your workbook myWb will not be closed! It stays open because myWb.Close is never reached. Change Exit Function to Exit For to just exit the loop and continue to close the workbook.

  4. Cells(1, i).Value is neither specified which workbook it is in nor which worksheet. This is not very reliable never call Cells or Range without specifying workbook and worksheet (or Excel will guess which one you mean, and Excel can fail if you are not precise).

    Therfore I recommend to use something like myWb.Worksheets(1).Cells(1, i).Value if you always mean the first worsheet in that workbook. Alternatively if it has a defined name using its name would be more reliable: myWb.Worksheets("SheetName").Cells(1, i).Value

  5. If you turn off ScreenUpdating don't forget to turn it on in the end.

  6. Error handling in case filename does not exist would be nice to not break the function.

  7. You can slightly improve speed by assuming Headers = "True" as default and just turn it False in case you find any non matching header. This way the variable is only set once to True instead of multiple times for every correct header.

    Public Function Headers(ByVal Filename As String) As String    
        Application.ScreenUpdating = False
    
        Dim flag As Boolean 'flag is never used! you can remove it
    
        On Error Resume Next 'error handling here would be nice to not break if filename does not exist.
        Dim myWb As Workbook
        Set myWb = Workbooks.Open(Filename:=Filename) 
        On Error Goro 0 'always reactivate error reporting after Resume Next!!!
    
        If Not myWb Is Nothing Then            
            Dim Arr() As Variant
            Arr = Array("col1", "col2")
    
            Headers = "True" 'assume True as default and just change it to False if a non matching header was found (faster because variable is only set true once instead for every column).
            Dim i As Long 'better use Long since there is no benefit in using Integer
            For i = 1 To UBound(arr) + 1 'use `ubound to find the upper index of the array, so if you add col3 you don't need to change the loop boundings
                If Not myWb.Worksheets(1).Cells(1, i).Value = Arr(i - 1) Then 'define workbook and worksheet for cells
                     Headers = "False , Not Found Header " & Arr(i - 1)
                     Exit For '<-- just exit loop but still close the workbook
                End If
            Next i
        Else
            Headers = "File '" & Filename & "' not found!"
        End If
    
        Application.ScreenUpdating = True
        myWb.Close
    End Function
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.