【VBA】Windows APIを使用して、FTPサーバーへファイルを送信/受信する

VBAから
 ・FTPサーバーへ
 ・ファイルを送信/受信
できます!

実現方法は
 ・Windows API
 ・FTPコマンド
の2種類あります!

この記事では
 ・Windows APIを使用する方法
を記載します!

FTPコマンドを使用する方法は、
以下の記事をご確認ください!



PR

前提(使用するWindows APIについて)

以下のWindows APIを使用することで、FTPサーバーへファイルを送信/受信できます。
・InternetOpen
・InternetConnect
・InternetCloseHandle
・FtpPutFile ※ファイルを送信する際に使用
・FTPGETFile ※ファイルを受信する際に使用

「Windows APIの定義をする部分」により少し長めなコードとなってしまいますが、
「FTPサーバーへファイルを送信/受信する部分」はそれほど長くなくてシンプルです。

PR

VBAコード(ファイル送信)

ここでは例として
 ・デスクトップ配下のファイル「test01.txt」を
 ・Windows APIを使用して、FTPサーバーへ送信
します。

大まかに以下の4つで構成されています。
・Windows APIの定義
・WinInetの取得
・FTPサーバーへ接続
・ファイルを送信

Option Explicit

'Windows API「InternetOpen」
Private Declare PtrSafe Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _
(ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _
ByVal sProxyBypass As String, ByVal lFlags As Long) As Long

'Windows API「InternetConnect」
Private Declare PtrSafe Function InternetConnect Lib "wininet.dll" _
Alias "InternetConnectA" _
(ByVal hInternetSession As Long, ByVal sServerName As String, _
ByVal nServerPort As Integer, ByVal sUsername As String, _
ByVal sPassword As String, ByVal lService As Long, _
ByVal lFlags As Long, ByVal lContext As Long) As Long

'Windows API「FtpPutFile」
Private Declare PtrSafe Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _
(ByVal hFtpSession As Long, ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean

'Windows API「InternetCloseHandle」
Private Declare PtrSafe Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer

'Windows APIを利用してFTPサーバーへファイルを送信するサンプルVBA
Sub ftpPutWinApiSample()

    '-----------------------------------------
    '接続情報を指定
    '-----------------------------------------
    Const FTP_SERVER As String = "ftpServerName"
    Const USER As String = "loginUser"
    Const PASSWORD As String = "password"
    
    Dim targetFile As String
    Dim serverFolderPath As String
    Dim localFolderPath As String
    Dim winInet As Long
    Dim con As Long
    Dim result As Boolean
    
    '送信ファイル
    targetFile = "test01.txt"
    'FTPサーバー側のフォルダ(保存先)
    serverFolderPath = "/temp/"
    'ローカル側のフォルダ
    localFolderPath = "C:\Users\user\Desktop\"

    'WinInetの取得
    winInet = InternetOpen(FTP_SERVER, 1, vbNullString, vbNullString, 0)
    If winInet = 0 Then
        MsgBox "winInetの取得に失敗しました!"
        Exit Sub
    End If
    
    'FTPサーバーへ接続
    con = InternetConnect(winInet, FTP_SERVER, 21, USER, PASSWORD, 1, 0, 0)
    If con = 0 Then
        MsgBox "FTPサーバーへの接続に失敗しました!"
        InternetCloseHandle (winInet)
        Exit Sub
    End If
    
    'ファイルを送信
    result = False
    result = FtpPutFile(con, localFolderPath & targetFile, serverFolderPath & targetFile, 1, 0)
    If (result) Then
        MsgBox "ファイルを送信できました!"
    Else
        MsgBox "エラー!ファイルを送信できませんでした!"
    End If

    '後片づけ
    InternetCloseHandle (winInet)
    InternetCloseHandle (con)
    
End Sub

Windows APIを定義します(4~24行目)。

接続情報として「FTPサーバー名」、「ログインユーザー名」、「パスワード」を指定します(32~34行目)。
※環境に合わせて変更してください。
※上記ではそれぞれ「ftpServerName」、「loginUser」、「password」としています。

「各種ファイル/フォルダ」を指定します(44~48行目)。
※状況に合わせて変更してください。

winInetを取得します(51~55行目)。
FTPサーバーへ接続します(58~63行目)。
ファイルを送信します(66~72行目)。

以下に失敗した場合、「Exitステートメント」により処理を中断します(54、62行目)。
・winInetの取得に失敗
・FTPサーバーへの接続に失敗

上記を実行すると、ファイアーウォールにより以下のような警告メッセージが表示されるかもしれません。

ファイアウォールによる警告メッセージ(英語版)
ファイアウォールによる警告メッセージ(英語版)

表示された場合、「アクセスを許可する」をクリックすることでFTPサーバーへファイルを送信/受信ができるようになります。


上記を実行すると、FTPサーバーへファイルが送信されます。

送信結果①
送信結果①
送信結果②
送信結果②

FTPサーバー上に既に同名ファイルが存在した場合は、上書きされます。

PR

VBAコード(ファイル受信)

ここでは例として 
 ・FTPサーバー上のファイル「test01.txt」をローカルの「temp」フォルダへ
 ・Windows APIを使用して、FTPサーバーから受信
します。

大まかに以下の4つで構成されています。
・Windows APIの定義
・WinInetの取得
・FTPサーバーへ接続
・ファイルを受信

Option Explicit

'Windows API「InternetOpen」
Private Declare PtrSafe Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _
(ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _
ByVal sProxyBypass As String, ByVal lFlags As Long) As Long

'Windows API「InternetConnect」
Private Declare PtrSafe Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _
(ByVal hInternetSession As Long, ByVal sServerName As String, _
ByVal nServerPort As Integer, ByVal sUsername As String, _
ByVal sPassword As String, ByVal lService As Long, _
ByVal lFlags As Long, ByVal lContext As Long) As Long

'Windows API「FTPGETFile」
Private Declare PtrSafe Function FTPGETFile Lib "wininet.dll" Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean

'Windows API「InternetCloseHandle」
Private Declare PtrSafe Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer

'Windows APIを利用してFTPサーバーからファイルを受信するサンプルVBA
Sub ftpGetWinApiSample()
    
    '-----------------------------------------
    '接続情報を指定
    '-----------------------------------------
    Const FTP_SERVER As String = "ftpServerName"
    Const USER As String = "loginUser"
    Const PASSWORD As String = "password"
    
    Dim targetFile As String
    Dim serverFolderPath As String
    Dim localFolderPath As String
    Dim winInet As Long
    Dim con As Long
    Dim result As Boolean
    
    '受信ファイル
    targetFile = "test01.txt"
    'FTPサーバー側のフォルダ
    serverFolderPath = "/temp/"
    'ローカル側のフォルダ(保存先)
    localFolderPath = "C:\Users\user\Desktop\temp\"
    
    'WinInetの取得
    winInet = InternetOpen(FTP_SERVER, 1, vbNullString, vbNullString, 0)
    If winInet = 0 Then
        MsgBox "winInetの取得に失敗しました!"
        Exit Sub
    End If
    
    'FTPサーバーへ接続
    con = InternetConnect(winInet, FTP_SERVER, 21, USER, PASSWORD, 1, 0, 0)
    If con = 0 Then
        MsgBox "FTPサーバーへの接続に失敗しました!"
        InternetCloseHandle (winInet)
        Exit Sub
    End If
    
    'ファイルを受信
    result = False
    result = FTPGETFile(con, serverFolderPath & targetFile, localFolderPath & targetFile, 0, 0, 1, 0)
    If (result) Then
        MsgBox "ファイルを受信できました!"
    Else
        MsgBox "エラー!ファイルを受信できませんでした!"
    End If
    
    '後片づけ
    InternetCloseHandle (winInet)
    InternetCloseHandle (con)
    
End Sub


上記を実行すると、FTPサーバーからファイルが受信されます。

受信結果①
受信結果①
受信結果②
受信結果②

ローカルの保存先に既に同名ファイルが存在した場合は、上書きされます。

PR

参考①

Windows APIを使用したFPTサーバーへのファイルの送信/受信は、WinInetを利用して実現しています。

WinInetの詳細は、公式サイトをご確認ください。

PR

参考②

FTPサーバーへファイルを送信/受信する前に、対象のファイルが存在有無を確認した方が良いかもです。

ファイルの存在有無の確認方法は、以下の記事をご確認ください。

PR

参考③

上記のVBAコードで使用した以下の詳細は、公式サイトをご確認ください。

●Exitステートメント

タイトルとURLをコピーしました