こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

VBAでHTTP接続?

最近、VBA for Access とBAPI21を利用してFTPによるファイルのアップロードができるようになった。というレベルのものが質問させていたただきます。

今回お聞きしたいのはFTPではなくHTTP接続を利用してファイルをアップロードする方法についてです。

ブラウザ上からある任意のサイトにたいして

>アカウント、パスワードの入力
>画面の移行
>ファイルの選択
>アップロードボタンの押す

この作業を手作業ではなくVBにやらせる方法を教えてください。
(ヒントで十分です。そこからはまず勉強します! 手掛かりがつかめません)

よろしくお願いします。

投稿日時 - 2009-11-25 18:23:58

QNo.5475485

困ってます

このQ&Aは役に立ちましたか?

18人が「このQ&Aが役に立った」と投票しています

回答(11)

ANo.11

>色々試行錯誤しまして、またご報告差し上げます。
>レスポンスはゆっくりになります。

 随分とゆっくりしていらっしゃるようですが、その後いかがお過ごしでしょうか?

 うっかりしておりましたが、随分前に、

>ファイルの選択
>アップロードボタンの押す

VBA を発見しておりましたので、お知らせいたします。

http://www.ka-net.org/office/of33.html#n03

投稿日時 - 2011-07-26 10:44:27

ANo.10

>環境に依存するエラーなのか、別のマシンでも試してみます。
 私の環境は「Windows XP Pro SP3」×「Microsoft Office Access 2003」×「Windows Internet Explorer 8」です。
 ネットワーク の設定は「広帯域に常時接続」しております。

 というか、
>'Busy'メソッドは失敗しました 'IWebBrowser2'オブジェクト
ということでしたら、
While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
の行を
While .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
に変えてお試しください。

投稿日時 - 2009-12-05 08:56:42

お礼

お返事遅れました。毎度、本当にありがとうございます。

ご提案ですが、う~ん、状況的には代わりがありません。
また、Vistaでも同様の現象が発生しました。

色々試行錯誤しまして、またご報告差し上げます。
レスポンスはゆっくりになります。
ホントに申し訳ありません

投稿日時 - 2009-12-07 18:33:01

ANo.9

>'Busy'メソッドは失敗しました 'IWebBrowser2'オブジェクト
 この実験にお使いになった パソコン の OS は何でしょうか?

>VistaではSendkeyは問題があるみたいです。
>私はXPなので今は問題ないのですが、将来を考えると...う~ん
とはお書きですが、もし、Vista でしたら、下記をお試しください。
 XP の場合でしたら、もうちょっと調べてみます。

【Vista の場合】
●Excel2007 VBAにてIE操作ができません
http://www.happy2-island.com/bbs/bbs.cgi?mode=past&no=665

>Vista の IE7において保護モード(protected mode) が有効になっていると...
という記述が見られます。

●Windows Vistaの保護モードとはなんですか?
http://faq.zaq.ne.jp/faq/1032net/app/servlet/qadoc?001984
の ページ の
>■ この現象を回避する方法
以下をご参照の上、「問題の発生しているサイトURLを信頼済みサイトの一覧に追加」なさってみてください。

 場合によっては、「保護モード(protected mode)」を無効にしなければならないかも知れませんが、とりあえず、上記をお試しになってみて、結果をお知らせください。

投稿日時 - 2009-12-04 22:07:54

お礼

お早い回答ありがとうございます!!!

う~ん、XPです。IEは7だった様な。(今手元にありません)
環境に依存するエラーなのか、別のマシンでも試してみます。

また進展ありましたらご連絡差し上げます。
どうか気長にお待ちになっていただけたら助かります。

投稿日時 - 2009-12-04 23:47:57

ANo.8

 こんばんゎ。DOUGLAS_ です。
>以前、別件でアドバイスいただいたときに、
>WaitをAccessでやるやり方がわかりませんでした(汗
>ここに関しては、どうもExcelと勝手が違うようですね?
 これに関しましては、ちょっとググってみて、
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub test()
 '・・・・・・・
 Sleep 3000
 '・・・・・・・
End Sub
で、簡単に実行することができました。

 が、しかし、私は Access VBA というか Access に関しては、素人以下ですので、[SendKeys ステートメント] にやられてしまいました。
 エクセル では、[SendKeys メソッド] ですが、Access になると、[SendKeys ステートメント] なんですね。
 しかも、[回答番号:No.5] に書いた ヘルプ はまったく通用しません。まさに、挙動不審です。

 で、[アップロードするファイルの選択] ダイアログ を開く前に、
.Visible = True
としていたのですが、却って、アップロード したと思われる頃に Visible にした方がよさ気です。

 現状、

Option Compare Database
Option Explicit
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub test()

で始まり、「.Visible = True」から「End With」までを、

  'ファイルの選択
  DoCmd.RunCommand acCmdCopy
  SendKeys "^V{ENTER}", False
  .Document.getElementsByName("ファイル 選択欄の name")(0).Click
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  Sleep 3000
  'アップロードボタンの押す
  .Document.getElementsByName("アップロードボタン の name")(0).Click
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  .Visible = True
 End With

に書き換えたら、どうにか動きました。

投稿日時 - 2009-11-30 22:15:42

補足

遅くなりました。
ログインが二箇所あり、例題の通りテストが出来るサイトを探し
見つからなかったので、ログインを二箇所行うように変更して、
HTMLを学びつつ...かなり、もだえながらやりましたので、ご返答遅れたことをお許しください(長い)。

そこまでよかったんですが、イキナリ

Const READYSTATE_COMPLETE As Long = 4
'ブラウザの起動
Set objIE = CreateObject("InternetExplorer.Application")
With objIE
'ログインページ1を開く
.Navigate strLoginURL1
While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
この一番下の行でえらーが発生。

実行エラー'-2147467259(80004005)'
'Busy'メソッドは失敗しました 'IWebBrowser2'オブジェクト

朗報をお伝えしたかったのですが、時間かけた割には、
全然手前でつまずいてしまってます。

もう少し調べてみようと思います。いつもご丁寧にありがとうございます。

投稿日時 - 2009-12-04 21:15:36

お礼

なんと、Access版までありがとうございます。
個の投稿がなかったら完全に挫折してました。

何とか今日やろうと思ったいのですが、まったく時間がとれずでした。
必ず報告させていただきます!

投稿日時 - 2009-12-01 22:33:52

ANo.7

ん~。。。
#ホントにたびたびすみません。DOUGLAS_ です。  (´ヘ`;)
 熱中する余り、肝心なコトを見落としておりました。

>VistaではSendkeyは問題があるみたいです。
>私はXPなので今は問題ないのですが、将来を考えると...う~ん
でしたね。
 申し訳ございません。  <(_ _)>

●Windows Vista 上の Office アプリケーションで SendKeys ステートメントが失敗する
http://support.microsoft.com/kb/931136/ja
>この問題を解決するには、最新の Microsoft Office 2003 Service Pack を入手します。

だそうです。

成功例)
●Vista上でAccess 2003
http://ptu.seesaa.net/article/128850070.html
●Vista/VB6.0
http://hanatyan.sakura.ne.jp/patio/read.cgi?mode=view2&f=103&no=23
など

投稿日時 - 2009-11-29 08:37:46

ANo.6

#たびたびすみません。DOUGLAS_ です。  <(_ _)>
  'アップロードボタンの押す
の前に
  Application.Wait (Now + TimeValue("0:00:3"))
を入れてみてください。

 パソコン の スペック にも依ろうかと存じますので、そこでダメなら前後させてみてください。

投稿日時 - 2009-11-29 00:23:52

お礼

これも書きなぐりですみません。
Application.Wait (Now + TimeValue("0:00:3"))

以前、別件でアドバイスいただいたときに、WaitをAccessでやるやり方がわかりませんでした(汗

ここに関しては、どうもExcelと勝手が違うようですね?

投稿日時 - 2009-11-30 19:47:53

ANo.5

[回答番号:No.1・3・4] の DOUGLAS_ です。
#~(^◇^)/ふふ やっとできました。
 というか、こんなのはダメかも知れませんが...。

 [SendKeys メソッド] というのが、どうも挙動不審で、イマイチつかめていなかったのですが、そういえば「ワンテンポ 遅れて実行されるようなぁ~...」雰囲気があったのを思い出しました。
 案の定、ヘルプ には、
-----------------------------------------------
SendKeys メソッドは、キー コードをキー バッファに入れます。そのため、キー コードを使うメソッドを呼び出す前に、SendKeys メソッドを呼び出さなくてはならない場合があります。たとえば、パスワードをダイアログ ボックスに送るときには、ダイアログ ボックスを表示する前に SendKeys メソッドを呼び出す必要があります。
-----------------------------------------------
と書いてあるではありませんかっ! (って、ここはご存じでしょうが...)

 ということで、Windows XP Pro SP3 × Excel 2003 VBA での操作になりまが。
 ポイントは [SendKeys メソッド] で ファイル名 を送るときに、
Application.SendKeys "D:\hoge\hoge.xls{ENTER}"
というように、ファイル名 そのものを送ると、[ファイル名(N):] の入力欄に「oge.xls」のような中途半端な文字列が入ったりするようですので、ワークシート の アクティブセル に ファイル名 を仕込んでおいて、それを コピー した後、
Application.SendKeys "^V{ENTER}"
というように、[Ctrl] + [V] で貼り付けると上手くいきましたゎ。

'----------------------------------------------
Option Explicit
Sub test()
 Dim objIE As Object
 Const READYSTATE_COMPLETE As Long = 4
 'ブラウザの起動
 Set objIE = CreateObject("InternetExplorer.Application")
 With objIE
  'ログインページを開く
  .navigate "ログインページのURL"
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  'アカウント、パスワードの入力
  .Document.getElementsByName("アカウント 入力欄の name")(0).Value = "アカウント"
  .Document.getElementsByName("パスワード 入力欄の name")(0).Value = "パスワード"
  '画面の移行
  .Document.getElementsByName("アカウント・パスワード 入力フォーム の name")(0).submit
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  'アップロードページに移行
  .navigate "アップロードページのURL"
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  .Visible = True
  'ファイルの選択
  ActiveCell.Copy
  Application.SendKeys "^V{ENTER}"
  .Document.getElementsByName("ファイル 選択欄の name")(0).Click
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  'アップロードボタンの押す
  .Document.getElementsByName("アップロードボタン の name")(0).Click
  While .Busy Or .ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
  Application.CutCopyMode = False
 End With
 Set objIE = Nothing
End Sub
'----------------------------------------------

 なお、
objIE.Document.getElementsByName("*** の name")(0)
の部分の「"*** の name"」に付きましては、当該ページ を ブラウザ で開いて、[表示(V)] - [ソース(C)] で、目的の タグ 周辺を覗いてみますと、
<input name="ファイル 選択欄の name" type="file" />
というように「name=」の後に ダブルクォーテーション で括って表示されている名前を使用します。
 「name=」がなくて、「id=」がある場合には、
objIE.Document.getElementById("*** の name")(0)
のようにして指定できます。

投稿日時 - 2009-11-29 00:08:55

お礼

なんと、ありがとうございます。
半分あきらめかけていたのですが、Sendkeyの問題にはパッチが出ていたんですね!?
ここ二日は忙しくて、テストが出来ておりませんが、取り急ぎお礼の返事を書かせていただきました。
ご親切にありがとうございました。

投稿日時 - 2009-11-30 19:43:55

ANo.4

[回答番号:No.1・3] の DOUGLAS_ です。懲りずに失礼いたします。

 私自身、いろいろとやってみましたが、どうも普通の手段で手に負える問題ではないようですね。
 いろいろと サーフィン していてご参考になりそうなものを見つけましたのでご覧ください。

http://oshiete1.goo.ne.jp/qa4624451.html
に書かれている Wendy02 さんの [回答番号:No.8] (回答日時:09/01/23 20:31)で紹介された「アップロードのいくつかの方法」の参照先にある
>投稿時間:2003/08/06(Wed) 20:26
>投稿者名:魔界の仮面弁士
>タイトル:Re^7: inetを使用してhttpでファイルアップロード
にご参考になりそうなことがいくつか書かれています。

 しかし、同じ Wendy02 さんが、後日(回答日時:09/11/15 11:08)回答された
http://soudan1.biglobe.ne.jp/qa5446271.html
にある [回答番号:No.4] には
>自動化のために・・・USWC を使わざるを得ない・・・
とも書かれています。


 なお、ブラウザ に依存するところが多いのかなとも存じますが、ブラウザ が IE8 の場合には、<input type="file"> の value が「C:\fakepath\ファイル名」になるという問題もあるようです。
 これにつきましては、当該サイト を IE の「信頼済みサイト」に登録することで回避できました。

投稿日時 - 2009-11-27 00:03:12

お礼

キャパオーバーになりそうで、お手上げ...と思いましたが、

http://hanatyan.sakura.ne.jp/logbbs/wforum.cgi?mode=allread&no=5232&page=900

に、
> しかし、Inetコントロール(のhttp機能)では、バイナリデータを送信する事ができないので、
> テキストファイルならば送信できますが、バイナリファイルの送信は難しいです。

とありました。今回はTextファイルに特化しているので道があるかも。
しかし、このInetというのを使いこなすのにも数回レベルアップしないと難しいかも...です。

本当にありがとうございました。
ここは、まだちょっと開設しておきます*^^*

投稿日時 - 2009-11-27 12:20:21

ANo.3

[回答番号:No.1] の DOUGLAS_ です。

 「ヒント」だけならと思って勇み足で書いてしまいましたが、実際に コーディング してみると、
'ファイルの選択
.document.getElementsByName("ファイル選択")(0).Value = "アップロードするファイル名"
が効きませんでした。

 理由は [回答番号:No.2] Wizard_Zero さんがお書きのことが原因のようです。
http://chaichan.web.infoseek.co.jp/qa6500/qa6937.htm

 ということで、[回答番号:No.1] は取り下げます。
 大変、失礼いたしました。

投稿日時 - 2009-11-25 22:39:23

お礼

お早いご返答ありがとうございました!

お返事がおそくなりましたが、うわ、簡単じゃないですね(ーー川)
なるほど、この手段を悪用する輩がいることがわかりました。

う~ん、断念しかないかなぁ。
クリップボード軽油は多分 Vista移行厳しいかもしれません。

以前利用していたAccessでのSendKeyがらみのものはVistaではセキュリティ上全く使えなくなってしまいました。

どなたか、継続してご意見お待ちしております。

投稿日時 - 2009-11-26 12:40:57

ANo.2

>ファイルの選択
↑ブラウザの自動操作だとここで引っかかると思います。

Webフォームのファイル選択要素(<input type="file">)は意図しないファイルの不正アップロードを防ぐため、スクリプトや外部から値の設定が出来ないようになっています。

安定性に欠く方法ですが、ブラウザを表示状態にしてファイル選択要素にフォーカスを移し、SendKeysでキーボード入力をエミュレートすればファイル名を書き込むことが出来ます。(これでちゃんとアップロードできるかは未確認)
動作中にマウスやキーボードが操作されると意図したとおりに動かない可能性があります。フォーム送信するときはファイル名が正しく記入されているかチェックしてからにしたほうがよいでしょう。(ファイル選択要素からの取得は可能です。)

投稿日時 - 2009-11-25 21:31:01

お礼

ありがとうございます。
同一の投降者からだとお礼をまとめてしまいました。

VistaではSendkeyは問題があるみたいです。
私はXPなので今は問題ないのですが、将来を考えると...う~ん

投稿日時 - 2009-11-27 12:03:31

ANo.1

>ヒントで十分です
 WEBで
CreateObject("InternetExplorer.application")
While .Busy Or .ReadyState <> 4: DoEvents: Wend
getElementById
getElementsByName
などを検索なさってみてください。

投稿日時 - 2009-11-25 20:41:23

あなたにオススメの質問