0

コードに問題があり、何が問題で、どのように修正すればよいかわかりません。私は Access 2007 で作業しています。次の関数 ExecCmd を使用しています。この関数は、コマンドラインを引数で実行し、実行が完了するまで待機して制御を Access に戻します。この関数を呼び出すと、0 ではなく 2 の終了コードが返され、実行したいバッチファイルが実行されません。

Private Type STARTUPINFO
      cb As Long
      lpReserved As String
      lpDesktop As String
      lpTitle As String
      dwX As Long
      dwY As Long
      dwXSize As Long
      dwYSize As Long
      dwXCountChars As Long
      dwYCountChars As Long
      dwFillAttribute As Long
      dwFlags As Long
      wShowWindow As Integer
      cbReserved2 As Integer
      lpReserved2 As Long
      hStdInput As Long
      hStdOutput As Long
      hStdError As Long
   End Type

   Private Type PROCESS_INFORMATION
      hProcess As Long
      hThread As Long
      dwProcessID As Long
      dwThreadID As Long
   End Type

   Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
      hHandle As Long, ByVal dwMilliseconds As Long) As Long

   Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
      lpApplicationName As String, ByVal lpCommandLine As String, ByVal _
      lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
      ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
      ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
      lpStartupInfo As STARTUPINFO, lpProcessInformation As _
      PROCESS_INFORMATION) As Long

   Private Declare Function CloseHandle Lib "kernel32" _
      (ByVal hObject As Long) As Long

   Private Declare Function GetExitCodeProcess Lib "kernel32" _
      (ByVal hProcess As Long, lpExitCode As Long) As Long

   Private Const NORMAL_PRIORITY_CLASS = &H20&
   Private Const INFINITE = -1&
   Private Const SW_HIDE = 0
   Private Const STARTF_USESHOWWINDOW = &H1

   Public Function ExecCmd(cmdline$)

      Dim proc As PROCESS_INFORMATION
      Dim start As STARTUPINFO
      Dim Ret&
      ' Initialize the STARTUPINFO structure:
      start.cb = Len(start)
      start.dwFlags = STARTF_USESHOWWINDOW
      start.wShowWindow = SW_HIDE
      ' Start the shelled application:
      Ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _
         NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)

      ' Wait for the shelled application to finish:
         Ret& = WaitForSingleObject(proc.hProcess, INFINITE)
         Call GetExitCodeProcess(proc.hProcess, Ret&)
         Call CloseHandle(proc.hThread)
         Call CloseHandle(proc.hProcess)
         ExecCmd = Ret&
   End Function

本当に奇妙なのは、ExecCmd を呼び出す前に次の関数 OuvrirUnFichier を呼び出すと、すべてが完全に正常に機能することです。

   ' Déclaration de l'API
Private Declare Sub PathStripPath Lib "shlwapi.dll" Alias "PathStripPathA" (ByVal pszPath As String)
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _
                   "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
 ' Structure du fichier
Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
 ' Constantes
Private Const OFN_READONLY = &H1
Private Const OFN_OVERWRITEPROMPT = &H2
Private Const OFN_HIDEREADONLY = &H4
Private Const OFN_NOCHANGEDIR = &H8
Private Const OFN_SHOWHELP = &H10
Private Const OFN_ENABLEHOOK = &H20
Private Const OFN_ENABLETEMPLATE = &H40
Private Const OFN_ENABLETEMPLATEHANDLE = &H80
Private Const OFN_NOVALIDATE = &H100
Private Const OFN_ALLOWMULTISELECT = &H200
Private Const OFN_EXTENSIONDIFFERENT = &H400
Private Const OFN_PATHMUSTEXIST = &H800
Private Const OFN_FILEMUSTEXIST = &H1000
Private Const OFN_CREATEPROMPT = &H2000
Private Const OFN_SHAREAWARE = &H4000
Private Const OFN_NOREADONLYRETURN = &H8000
Private Const OFN_NOTESTFILECREATE = &H10000

Private Const OFN_SHAREFALLTHROUGH = 2
Private Const OFN_SHARENOWARN = 1
Private Const OFN_SHAREWARN = 0

Public Function OuvrirUnFichier(Handle As Long, _
                                titre As String, _
                                TypeRetour As Byte, _
                                Optional TitreFiltre As String, _
                                Optional TypeFichier As String, _
                                Optional RepParDefaut As String) As String
 ' OuvrirUnFichier est la fonction à utiliser dans votre formulaire pour ouvrir _
 ' la boîte de dialogue de sélection d'un fichier.
 ' Explication des paramètres
    ' Handle = le handle de la fenêtre
    ' Titre = titre de la boîte de dialogue
    ' TypeRetour (définit la valeur, de type String, renvoyée par la fonction)
        ' 1 = chemin complet + nom du fichier
        ' 2 = nom fichier seulement
    ' TitreFiltre = titre du filtre
        ' Exemple: fichier Access
        ' N'utilisez pas cet argument si vous ne voulez spécifier aucun filtre
    ' TypeFichier = extention du fichier (sans le .)
        ' Exemple: MDB
        ' N'utilisez pas cet argument si vous ne voulez spécifier aucun filtre
    ' RepParDefaut = répertoire d'ouverture par défaut
        ' Exemple: C:\windows\system32
        ' Si vous laissez l'argument vide, par défaut il se place dans le répertoire de votre application

Dim StructFile As OPENFILENAME
Dim sFiltre As String

 ' Construction du filtre en fonction des arguments spécifiés
If Len(TitreFiltre) > 0 And Len(TypeFichier) > 0 Then
  sFiltre = TitreFiltre & " (" & TypeFichier & ")" & Chr$(0) & "*." & TypeFichier & Chr$(0)
End If
sFiltre = sFiltre & "Tous (*.*)" & Chr$(0) & "*.*" & Chr$(0)

 ' Configuration de la boîte de dialogue
  With StructFile
    .lStructSize = Len(StructFile) ' Initialisation de la grosseur de la structure
    .hwndOwner = Handle ' Identification du handle de la fenêtre
    .lpstrFilter = sFiltre ' Application du filtre
    .lpstrFile = String$(254, vbNullChar) ' Initialisation du fichier '0' x 254
    .nMaxFile = 254 ' Taille maximale du fichier
    .lpstrFileTitle = String$(254, vbNullChar) ' Initialisation du nom du fichier '0' x 254
    .nMaxFileTitle = 254  ' Taille maximale du nom du fichier
    .lpstrTitle = titre ' Titre de la boîte de dialogue
    .flags = OFN_HIDEREADONLY  ' Option de la boite de dialogue
    If ((IsNull(RepParDefaut)) Or (RepParDefaut = "")) Then
        RepParDefaut = CurrentDb.Name
        PathStripPath (RepParDefaut)
        .lpstrInitialDir = Left(CurrentDb.Name, Len(CurrentDb.Name) - Len(Mid$(RepParDefaut, 1, _
InStr(1, RepParDefaut, vbNullChar) - 1)))
        Else: .lpstrInitialDir = RepParDefaut
    End If
  End With
If (GetOpenFileName(StructFile)) Then ' Si un fichier est sélectionné
    Select Case TypeRetour
      Case 1: OuvrirUnFichier = Trim$(Left(StructFile.lpstrFile, InStr(1, StructFile.lpstrFile, vbNullChar) - 1))
      Case 2: OuvrirUnFichier = Trim$(Left(StructFile.lpstrFileTitle, InStr(1, StructFile.lpstrFileTitle, vbNullChar) - 1))
    End Select
  End If
End Function

問題がどこから来たのか誰にも分かりますか? 何が起こっているか、またはそれを解決する方法は?OuvrirUnFichier が問題を解決する理由は何ですか? どうもありがとうございました

私は calc.exe を試してみましたが、それは実際に動作しますが、私がしたいのは、このコードで作成したバッチファイルを実行することです:

Open vPath & "\FtpComm.txt" For Output As fNum
Connexion (fNum) 'function that prints lines to connect to FTP server
Print #fNum, "put " & vFile & " Temp.mdb" 'upload local filename to server file 
Deconnexion (fNum) 'function that prints lines to disconnect from FTP server
Close fNum
Open vPath & "\doFtp.bat" For Output As batFileHandle
Print #batFileHandle, "ftp -s:FtpComm.txt >output.txt" '
Close batFileHandle

RetVal = ExecCmd(vPath & "\doFtp.bat")

.bat ファイルは正しく作成されています。手動でクリックすると実行され、ExecCmd で実行したときにやりたいことが実行されます。

4

2 に答える 2

0

ExecCmd()32 ビット Vista で Access_2010の関数を使用して単純な「Hello world」バッチ ファイルを実行しようとしましたが、Access がハングするだけでした (使用した場合でもcmd.exe /c hello.bat)。Runあなたの特定の要件については、次の方法を使用することでより適切にサービスを提供できると思いますWscript.Shell

Public Function myExecCmd(cmdstr As String) As Long
Dim wsh As Object
Set wsh = CreateObject("Wscript.Shell")
myExecCmd = wsh.Run(cmdstr, 1, True)
End Function

さらに、元のアプローチは 64 ビット Access では (32 ビット API 呼び出しのため) 「すぐに」機能しませんが、このアプローチは 32 ビット バージョンと 64 ビット バージョンの両方の Access でうまく機能するはずです。 . Runメソッドの詳細については、こちらを参照してください

于 2013-03-15T16:36:49.943 に答える
0

私の問題の解決策を見つけました。Access は、私が作成したファイルを探す場所を知るのに苦労しました。関数 OuvrirUnFichier により、彼は適切なディレクトリに配置され、適切に機能することができました。.txt ファイルと .bat ファイルを作成するコードを次のように変更しました。

 Open vPath & "\FtpComm.txt" For Output As fNum
Connexion (fNum)
Print #fNum, "get " & Fichier & " " & vPath & "\Temp.mdb" 'upload local filename to server file  : LocalFile [RemoteFile] LocalFile
Deconnexion (fNum)
Close fNum
Open vPath & "\doFtp.bat" For Output As batFileHandle
Print #batFileHandle, "ftp -s:" & vPath & "\FtpComm.txt >" & vPath & "\output.txt" 'execute le fichier batch et écrit les output dans le fichier output
Close batFileHandle
RetVal = ExecCmd(vPath & "\doFtp.bat")

そして今、それは完全に機能します!:D

于 2013-03-16T15:26:47.787 に答える