Использование FTP в VBA - PullRequest
       4

Использование FTP в VBA

1 голос
/ 25 августа 2011

Я написал код VBA, который создает TXT-файл с Job-Code для хоста IBM на основе данных Excel (Websphere MQ Define Job).

Было бы здорово иметь возможность автоматически передавать этот файл на хост через FTP. На данный момент я делаю это вручную через:

(комментарий: LPAR = Host-Name)

ftp <LPAR>
'user'
'password'
put 'dateiname'

Работает вполне нормально. Но я не знаю, как перенести это в код VBA. Я нашел похожий вопрос здесь и там было опубликовано это решение:

Public Sub FtpSend()

    Dim vPath As String
    Dim vFile As String
    Dim vFTPServ As String
    Dim fNum As Long

    vPath = ThisWorkbook.path
    vFile = "path"
    vFTPServ = "<LPAR>"

    'Mounting file command for ftp.exe
    fNum = FreeFile()
    Open vPath & "\FtpComm.txt" For Output As #fNum
    Print #1, "user *******" ' your login and password"
    'Print #1, "cd TargetDir" 'change to dir on server
    Print #1, "bin" ' bin or ascii file type to send
    Print #1, "put " & vPath & "\" & vFile & " " & vFile ' upload local filename to     server     file
    Print #1, "close" ' close connection
    Print #1, "quit" ' Quit ftp program Close

    Shell "ftp -n -i -g -s:" & vPath & "\FtpComm.txt " & vFTPServ, vbNormalNoFocus

    SetAttr vPath & "\FtpComm.txt", vbNormal
    Kill vPath & "\FtpComm.txt"

End Sub

Я не уверен, полностью ли я понимаю код. Я думаю, что создаю фиктивный файл, FtpComm.txt, с пользовательскими данными и содержимым, и использую этот файл для открытия соединения и отправки данных.

Работает, как-то, до точки

*SetAttr vPath & "\FtpComm.txt", vbNormal*

Там я получаю сообщение об ошибке

Runtime-Error: 55 - Файл уже открыт.

На этом этапе устанавливается соединение с LPAR. Но что делает "SetAttr ..."? Это точка, где ввод сделан? Что мне делать?

Ответы [ 4 ]

8 голосов
/ 25 августа 2011

Две вещи.

Сначала вы открываете файл под номером #fNum, полученным из fNum = FreeFile(), а затем просто предполагаете, что это вернет 1, как в Print #1 и т. Д .:

Open vPath & "\FtpComm.txt" For Output As #fNum
Print #1, "user *******" ' your login and password"

Измените все свои Print #1 на Print #fNum.

Во-вторых, вы открываете свой файл для ввода-вывода, но никогда не закрываете его.Поэтому, конечно, когда вы пытаетесь изменить его атрибуты или удалить его, система будет жаловаться, что он уже открыт и используется.Решение состоит в том, чтобы закрыть файл - что вы всегда должны делать, как только вы закончите запись / чтение из файла.

Close #fNum ' add this line
' Can now manipulate the file without risking conflict

Shell "ftp -n -i -g -s:" & vPath & "\FtpComm.txt " & vFTPServ, vbNormalNoFocus

SetAttr vPath & "\FtpComm.txt", vbNormal
Kill vPath & "\FtpComm.txt"

Что касается того, что ваш код делает на высоком уровне: если вы введете ftp -help в командной строке, вы увидите, что означают эти флаги -n -i -g -s.Так что да, вы пишете команды FTP в файл FtpComm.txt, а затем передаете этот файл в ftp с помощью флага -s.

-s:filename    Specifies a text file containing FTP commands; the
               commands will automatically run after FTP starts.
4 голосов
/ 26 августа 2011

Вы на правильном пути, и следуя ответу Жан-Франсуа, вы попадете туда.

Если вы хотите что-то, что вы можете вырезать и вставить, вы можете попробовать код ниже. Это вариант того, что я написал несколько лет назад.

Самым большим предупреждением является то, что после того, как вы обработаете команду FTP, вы не будете знать, действительно ли файл был передан, пока не проверите вручную.

Но, если вы ограничены строгим VBA , то вот путь:

Option Explicit
Const FTP_ADDRESS = "ftp.yourdestination.com"
Const FTP_USERID = "anon"
Const FTP_PASSWORD = "anon"

Sub Macro1()
    If Not SendFtpFile_F() Then
        MsgBox "Could not ftp file"
    Else
        MsgBox "Sent"
    End If
End Sub

Function SendFtpFile_F() As Boolean
    Dim rc As Integer
    Dim iFreeFile As Integer
    Dim sFTPUserID As String
    Dim sFTPPassWord As String
    Dim sWorkingDirectory As String
    Dim sFileToSend As String

    Const FTP_BATCH_FILE_NAME = "myFtpFile.ftp"
    Const INCREASED_BUFFER_SIZE = 20480

    SendFtpFile_F = False

    sWorkingDirectory = "C:\YourWorkingDirectory\"
    sFileToSend = "NameOfFile.txt"

    On Error GoTo FtpNECAFile_EH

    'Kill FTP process file if it exists
    If Dir(sWorkingDirectory & FTP_BATCH_FILE_NAME) <> "" Then
        Kill sWorkingDirectory & FTP_BATCH_FILE_NAME
    End If

    'Create FTP process file
    iFreeFile = FreeFile
    Open sWorkingDirectory & FTP_BATCH_FILE_NAME For Output As #iFreeFile
    Print #iFreeFile, "open " & FTP_ADDRESS
    Print #iFreeFile, FTP_USERID
    Print #iFreeFile, FTP_PASSWORD
    Print #iFreeFile, "mput " & sWorkingDirectory & sFileToSend
    Print #iFreeFile, "quit"
    Close #iFreeFile

    'Shell command the FTP file to the server
    Shell "ftp -i -w:20480 -s:" & sWorkingDirectory & FTP_BATCH_FILE_NAME

    SendFtpFile_F = True

    GoTo FtpNECAFile_EX

    FtpNECAFile_EH:
        MsgBox "Err", Err.Name

    FtpNECAFile_EX:

    Exit Function

End Function

Примечание. При пошаговом выполнении кода вы можете ввести в ближайшем окне следующую команду, а затем скопировать / вставить результаты в окно командной строки:

? Shell "ftp -i -w:20480 -s:" & sWorkingDirectory & FTP_BATCH_FILE_NAME
1 голос
/ 25 августа 2011

SetAttr используется для установки атрибутов файла (или папки). В вашем случае он устанавливает значение «Нормальное» (не скрытое, только для чтения и т. Д.). Однако, поскольку ваш файл все еще открыт из вызова «Открыть для вывода», он завершится ошибкой «Файл уже открыт».

Я не вижу никакой причины, по которой вызывается функция SetAttr, поскольку вы нигде не меняете атрибуты. Поэтому не стесняйтесь удалить его и посмотрите, работает ли он по-прежнему.

0 голосов
/ 07 марта 2013

В первом примере после предложения

Print #1, "quit" ' Quit ftp program Close

Вы должны закрыть файл, используемый для связи с предложением:

Close #fNum

Поскольку этот файл в настоящее время используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...