[EXCEL/VBA] Gebruik van command-line switches

Pagina: 1
Acties:
  • 157 views sinds 30-01-2008
  • Reageer

  • De doorloper
  • Registratie: Januari 2003
  • Laatst online: 20-05 19:19
Ik probeer voor elkaar te krijgen om in een Excelbestand een array te kunnen gebruiken waarin de parameters zitten die vanaf de command line zijn meegegeven.

Op http://www.mrexcel.com/archive/VBA/15657.html heb ik een handleiding hiervoor gevonden, maar die werkt niet helemaal vlekkeloos. De handleiding zegt dat ik een procedure moet maken met de naam Auto_open en geeft daarbij de volgende voorbeeldcode:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Option Base 1

Declare Function GetCommandLineA Lib "Kernel32" () As String

Sub Auto_Open()
    Dim CmdLine As String     'command-line string
    Dim argv() As String      ' array for storing the parameters
    Dim argc As Integer       ' number of params
    Dim pos1, pos2 As Integer
    argc = 0
    
MsgBox "voor GetCommandLineA"
    CmdLine = GetCommandLineA
MsgBox "na GetCommandLineA: " & vbCrLf & CmdLine
    On Error Resume Next
    pos1 = WorksheetFunction.Search("/", CmdLine, 1) + 1
    pos1 = WorksheetFunction.Search("/", CmdLine, pos1) + 1
    
    Do While Err = 0
        pos2 = WorksheetFunction.Search("/", CmdLine, pos1)
        argc = argc + 1
        ReDim Preserve argv(argc)
        argv(argc) = Mid(CmdLine, pos1, IIf(Err, Len(CmdLine), pos2) - pos1)
        MsgBox "Argument " & argc & ": " & argv(argc)
        pos1 = pos2 + 1
    Loop
End Sub


(die 2 MsgBox'en zijn van mij)

Wanneer ik het excel-bestand start door in de Start/Uitvoeren-regel van Windows dit in te typen: "test.xls /e/testje" krijg ik de MsgBox voor de api-call wel te zien, maar krijg ik bij de api-call een DrWatson op EXCEL.EXE voor de kiezen. Als ik bij Start/Uitvoeren "excel test.xls /e/testje" intyp, dan krijg ik de beide MsgBox-en te zien, alleen de messagebox in de do/while loop krijg ik nul keer te zien en de msgbox vlak na de apicall toont het volledige pad naar EXCEL.EXE.

Weet iemand wat ik fout doe? De bedoeling is dat ik dus vanaf een batch-file Excel start, en dat de VBA-code die ik in Excel heb staan gebruik kan maken van teksten die in parameters is meegegeven.

Het besturingssysteem is Windows NT 4.0 en de versie van Excel is 2000.

  • KingRichard
  • Registratie: September 2002
  • Laatst online: 21-03-2025

KingRichard

former Duke of Gloucester

Volgens deze bron moet dat anders:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Private Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As Long

Private Sub Form_Paint()
    'Show the commandline
    MessageBoxEx Me.hwnd, "The command line: " + GetCommLine, "Command Line ..."
End Sub

Private Function GetCommLine() As String
    Dim RetStr As Long, SLen As Long
    Dim Buffer As String
    'Get a pointer to a string, which contains the command line
    RetStr = GetCommandLine
    'Get the length of that string
    SLen = lstrlen(RetStr)
    If SLen > 0 Then
        'Create a buffer
        GetCommLine = Space$(SLen)
        'Copy to the buffer
        CopyMemory ByVal GetCommLine, ByVal RetStr, SLen
    End If
End Function
Dit is een ingekorte versie van het voorbeeld. Wat opvalt is dat de API-call gedaan wordt "As Long" terwijl jij het doet "As String".

a horse! a horse! my kingdom for a horse! (exeunt)
[got.profile] | [t.net.profile] | [specs]


  • De doorloper
  • Registratie: Januari 2003
  • Laatst online: 20-05 19:19
Deze is ook logischer omdat je nu met een pointer werkt zoals dat hoort bij API-calls. Alleen de CopyMemory (RTLMoveMemory uit kernel32.dll) wordt niet herkend. Ik heb al wat zitten zoeken naar die functie, maar het is iig geen procedure en verder weet ik niet waarom dit niet werkt. Ook de "byVal"-benadering van parameters bij de aanroep van RTLMoveMemory is het niet, dat heb ik ook geprobeerd.

********** EDIT 1 **********
inmiddels wordt ie wel herkend, alleen krijg ik de parameters niet, maar het commando zonder argumenten. Ik gebruik deze code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Option Explicit
Option Base 1

Private Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Auto_Open()
    SetArgvAndArgc
End Sub

Private Function GetCommLine() As String
    Dim RetStr As Long, SLen As Long
    Dim Buffer As String
    
    'Get a pointer to a string, which contains the command line
    RetStr = GetCommandLine
    'Get the length of that string
    SLen = lstrlen(RetStr)
    If SLen > 0 Then
        'Create a buffer
        GetCommLine = Space$(SLen)
        'Copy to the buffer
        Call CopyMemory(ByVal GetCommLine, ByVal RetStr, SLen)
    End If
End Function

Private Sub SetArgvAndArgc()
    Dim sCmdLine As String
    
    sCmdLine = GetCommLine
    MsgBox sCmdLine
End Sub


Als ik het commando
code:
1
excel c:\test.xls /e/one/two/three
intik, dan krijg ik in de MsgBox te zien:
code:
1
"C:\PROGRA~1\MICROS~1\Office\EXCEL.EXE" test.xls
Wat ik niet zie en wel wil heben, is
code:
1
/e/one/two/three


********** EDIT 2 **********

Als ik het zo intik:
code:
1
excel /one/two/three c:\test.xls
werkt het wel. Dan kan ik in VB met stringmanipulatie "one", "two" en "three" er wel uit vissen... _/-\o_

[ Voor 74% gewijzigd door De doorloper op 31-03-2004 15:59 ]


  • De doorloper
  • Registratie: Januari 2003
  • Laatst online: 20-05 19:19
En voor de liefhebber het eindresultaat:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
'
' Dit bestand starten vanaf cmd.exe, met het volgende commando:
'    START EXCEL /argv1/argv2/argv3/ BESTAND.XLS
'

Option Explicit
Option Base 1

Dim argc As Integer
Dim argv() As String

Private Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Auto_Open()
    SetArgvAndArgc
End Sub

Private Function GetCommLine() As String
    Dim RetStr As Long, SLen As Long
    Dim Buffer As String
    
    'Get a pointer to a string, which contains the command line
    RetStr = GetCommandLine
    'Get the length of that string
    SLen = lstrlen(RetStr)
    If SLen > 0 Then
        'Create a buffer
        GetCommLine = Space$(SLen)
        'Copy to the buffer
        Call CopyMemory(ByVal GetCommLine, ByVal RetStr, SLen)
    End If
End Function

Private Sub SetArgvAndArgc()
    Dim sCmdLine As String
    Dim pos1, pos2 As Integer
    
    argc = 0
    sCmdLine = GetCommLine
    
    On Error Resume Next ' voor de WorksheetFunction "Search"
    
    pos1 = WorksheetFunction.Search("/", sCmdLine, 1) + 1
    
    Do While Err = 0
        pos2 = WorksheetFunction.Search("/", sCmdLine, pos1)
        argc = argc + 1
        ReDim Preserve argv(argc)
        argv(argc) = Mid(sCmdLine, pos1, IIf(Err, Len(sCmdLine), pos2) - pos1)
        pos1 = pos2 + 1
    Loop
    
    ' Verwijder de laatse entry in de array
    ReDim argv(argc - 1)
    argc = argc - 1
End Sub


Als je nu start met

code:
1
start excel /a/b/c/ test.xls


dan krijg je een integer "argc" met de waarde 3 en een array van strings "argv" met de waarden a, b en c.