Webで保存方法を探るが、なかなか、ヒットしない。
みなさん、ダイアログにSendKeysしたりとイロイロ苦労しているみたいです。
しかたないので、マイクロソフトのページをみてみる。
使えそうな?
URLDownloadToFile?ってヤツが載ってました。
日本語のサポートかと思ったら、ヘッダ部分だけ日本語?
こんなのアリなの?
なんて、文句は置いといて、下記のURLに情報載ってます。
http://support.microsoft.com/support/kb/articles/q244/7/57.asp
The WebBrowser control and Internet Explorer have Save and Save As options
that can be used to save files using the ExecWB command. However,
this involves prompting from the user.
There is no way to suppress this prompt.
To save files to the hard-disk without prompting,
use the URLDownloadToFile API from URLMON.
MORE INFORMATION
The declaration for URLDownloadToFile is as follows:
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal _
szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
The function can be called as follows:
returnValue = URLDownloadToFile(0, "http://www.microsoft.com/ms.htm" _
"c:\ms.htm", 0, 0)
Note that when downloading HTML files,
embedded content like images and objects will not be downloaded.
/*
* 3.単体でテストを行う
*/
URLDownloadToFile って API が URLMON ってところにあるらしい。
APIの宣言文はそのままコピーして、下記のように使ってみた。
'URLDownloadToFile API from URLMON.
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal _
szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Sub aaa()
Const strURL = "http://www.ken3.org/index.html"
Dim strFNAME As String 'ダウンロード先(パス+ファイル名)
Dim returnValue
'ファイル名をブックのパス+test.htmlとする
strFNAME = ThisWorkbook.Path & "\test.html"
'URLDownloadToFile API をコールする
returnValue = URLDownloadToFile(0, strURL, strFNAME, 0, 0)
'結果の表示
MsgBox "結果は:" & returnValue
MsgBox strFNAME & "に保存されました"
End Sub
さてと、単体テストが終了したので、
PDFファイルを取り出してみますか。
※PDFと思ったけど、PDFファイルって、サイズ大きいので、
.htmlをテストでダウンロードしてます。
目的のファイルへ拡張子のチェック部分を変更してくださいね。
リンク先のオブジェクトの取り出しは、
http://www.ken3.org/backno/backno_vba15.html#71
の
No.71 IE操作 リンク先を取出す .Document.links(i).href
で、
.Documentオブジェクトのリンクを探り、
.href .outertext .outerHTML を使ってみました。
objIE.Document.links.Length
でリンクの数を取得できるので、
'リンク数分まわす
For i = 0 To objIE.Document.links.Length - 1
Cells(nYLINE, "A") = "'" & objIE.Document.links(i).outerText
Cells(nYLINE, "B") = "'" & objIE.Document.links(i).href
Cells(nYLINE, "C") = "'" & objIE.Document.links(i).outerHTML
nYLINE = nYLINE + 1 'セット位置を+1する
Next i
みたいにして、リンクを取り出してました。
ここに、ファイルのダウンロード処理をいれてみます。
メインのルーチンで
^^^^^^^^^^^^^^^^^^
・IE起動
・目的の画面表示、
・リンクのループ、リンク先URLをサブに渡す
サブのルーチンで、リンク先URLを受け取り
^^^^^^^^^^^^^^^^^^
・拡張子のチェック
・ファイル名の作成
・実際のダウンロードを行う
と処理を分けてみたいと思います。
'URLDownloadToFile API from URLMON.
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal _
szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
とAPIの宣言をしてから、
まずは、メインのルーチンを作成します。
Sub test_main()
Dim objIE As Object
Dim time10 As Date
Dim strURL As String
Dim i As Integer
Dim nYLINE As Integer
On Error GoTo EMSG
'IEの起動
Set objIE = CreateObject("InternetExplorer.application")
objIE.Visible = True '見えるようにする
objIE.GoHome '初期ページの表示
Do While objIE.Busy = True '起動まで待つ
DoEvents
Loop
'Excelをアクティブにする。
AppActivate "Microsoft Excel"
'初期処理
Rows("13:1000").Select '結果の表示エリアをクリアする
Selection.Delete Shift:=xlUp
nYLINE = 13 '13行目からデータをセットするので
'読み込むページのURLを代入
strURL = "http://www.ken3.org/backno/backno_vba15.html"
objIE.Navigate "" & strURL 'アドレスを渡し表示する
'読みこみ完了まで待つ
'30秒後を計算して、待つ
time10 = DateAdd("s", 30, Now())
Do While objIE.Busy = True
DoEvents
If time10 < Now() Then
Exit Do
End If
DoEvents
Loop
If objIE.Busy = True Then
Cells(nYLINE, "A") = "タイムアウトです、読み込みに失敗しました"
MsgBox "タイムアウトです、読み込みに失敗しました"
Exit Sub '関数を抜ける
End If
'リンクを探す
'リンク数分まわす
For i = 0 To objIE.Document.links.Length - 1
Cells(nYLINE, "A").Select '遊びでカーソル移動
DoEvents
Cells(nYLINE, "A") = "'" & objIE.Document.links(i).outerText
Cells(nYLINE, "B") = "'" & objIE.Document.links(i).href
'後ろが.htmlならファイルダウンロードの関数を呼ぶ
If Right(objIE.Document.links(i).href, 4) = "html" Then
Cells(nYLINE, "C") = Now '遊びで開始時刻をセット
'ダウンロード関数を呼ぶ
Call get_url_file(objIE.Document.links(i).href)
Cells(nYLINE, "D") = Now
End If
'次のセット位置にする
nYLINE = nYLINE + 1 'セット位置を+1する
Next i
objIE.Quit 'IEを閉じる
MsgBox "終了しました"
Exit Sub
EMSG:
Cells(nYLINE, 2) = "ERR"
objIE.Quit '
MsgBox "errが発生しました"
Exit Sub
End Sub
Sub get_url_file(strURL As String)
Dim strFNAME As String 'ダウンロード先(パス+ファイル名)
Dim strWORK As String '後ろから/を探し、ファイル名を取り出す
Dim returnValue
Dim n As Integer
'ファイル名を取り出す
For n = Len(strURL) To 1 Step -1 '後ろから/を探す
If Mid(strURL, n, 1) = "/" Then
Exit For '/が見つかったらループを抜ける
End If
Next n
strWORK = Mid(strURL, n + 1) '/の次からファイル名なのでn+1から
'ファイル名をブックのパス+\+取り出したファイル名とする
strFNAME = ThisWorkbook.Path & "\" & strWORK
'strFNAME = "C:\DATA\AAA\" & strWORK と固定のパスでもOKだけど
'URLDownloadToFile API をコールする
returnValue = URLDownloadToFile(0, strURL, strFNAME, 0, 0)
End Sub
Sub aaa()
'ChDir "e:\work"
Dim strFPTN As String 'ファイルパターン?
strFPTN = "lzhファイル(vb*.lzh),vb*.lzh"
Dim strFN As String
strFN = Application.GetOpenFilename(strFPTN)
MsgBox strFN
End Sub
あれ・・ダメなの?
でも、拡張子の指定は下記のようにするとOKなんだけど。
Sub bbb()
'ChDir "e:\work"
Dim strFPTN As String 'ファイルパターン?
strFPTN = "lzhファイル(*.lzh), *.lzh"
strFPTN = strFPTN & ",テキストファイル, *.txt;*.csv"
Dim strFN As String
strFN = Application.GetOpenFilename(strFPTN)
MsgBox strFN
End Sub
Private Sub UserForm_Initialize()
'フォームの初期化イベントでリストボックスにデータをセットする
Dim strWORK As String
Me.ListBox1.Clear '.Clearで内容を全てクリア
strWORK = Dir("vb*.lzh") 'カレントのVB*.lzhを検索する
While strWORK <> ""
'取得したファイル名をリストに追加する、ITEMの追加
Me.ListBox1.AddItem (strWORK)
'次のファイル名を取得する
strWORK = Dir() '引数無しで呼ぶと次のファイル名がセットされる
Wend
End Sub
Private Sub btn01_Click()
Dim strDATA As String
strDATA = Me.ListBox1.Text '.Textプロパティの値を代入
If strDATA = "" Then
MsgBox "データを選択してからボタンを押してね"
Else
MsgBox "選択されたデータは、" & strDATA
End If
End Sub
Sub ccc()
'ChDrive "E" 'ドライブの変更
'ChDir "e:\work" 'フォルダーの変更
UserForm1.Show 'ユーザーフォームを表示する
End Sub
まぁ、こんな感じで、
ChDrive "E" 'ドライブの変更
ChDir "e:\work" 'フォルダーの変更
ドライブだったらこれでOKですね。
自分の環境に固定の場所を直してコメントを外してください。
※えっ、途中で変更したいって?まぁ、今回はカンベンしてよ・・・
ユーザーフォームで、ファイルを選択後、
LHAのファイルを解凍します。
userform1のモジュールです。
ボタンが押されたら、解凍するためにDLLを呼んでます。
Private Declare Function Unlha Lib "UNLHA32.DLL" (ByVal Callhwnd As Long, _
ByVal LHACommand As String, ByVal RetBuff As String, _
ByVal RetBuffSize As Long) As Long
Private Sub btn01_Click()
Dim strDATA As String
strDATA = Me.ListBox1.Text '.Textプロパティの値を代入
If strDATA = "" Then
MsgBox "データを選択してからボタンを押してね"
Exit Sub
End If
'********* UnLHA32.DLLを使ってLZHファイルを解凍する *********
Dim Ret As String * 255 'UnLHAからの結果を入れるバッファ(長さ255バイト)
Dim SendStr As String 'コマンド゛文字列
Dim sourceFile As String '解凍する圧縮ファイル
Dim targetDir As String '解凍先ディレクトリ
Dim Result As Long '戻り値
Dim Msg1 As String
'↓解凍先ディレクトリ
'targetDir = "e:\work\test\" '←固定値をセットしてもいいし
targetDir = CurDir() & "\" 'カレントディレクトリをセットする
'↓解凍したい.lzhファイル
sourceFile = CurDir() & "\" & strDATA
'↑選択されたファイル名を+して、フルパスを作成する
'C:\Documents and Settings\ken3\My Documents
'みたいに、スペース付のフォルダの予防で”chr(&h22)を付ける
sourceFile = Chr(&H22) & sourceFile & Chr(&H22)
targetDir = Chr(&H22) & targetDir & Chr(&H22)
'"C:\Documents and Settings\ken3\My Documents"とダブルコーテーション付にする
'ここで、コマンドを作っている
SendStr = "e " & sourceFile & " " & targetDir
'(スペースで区切っていることに注意)
Result = Unlha(0, SendStr, Ret, 255) 'UnLHA実行!
If Result = 0 Then MsgBox (Ret) '解凍に成功したら、結果報告
'作業が終了、フォームを閉じる
Unload Me
End Sub
とくにポイントは無いんだけど、
ファイル名で(フォルダーで)
My Documents
みたいに、スペースが入っているフォルダーがあります。
これをそのままスペース区切りのコマンドに乗せると、
e C:My Documents\vb00aaa.lzh C:My Documents\
となり、正しく渡らないので、
""を付け(””で囲い)
e "C:My Documents\vb00aaa.lzh" "C:My Documents\"
がパラメータで渡るように細工してます。
あとは、うまくアレンジして、解凍処理を作れると思います。
フォームの初期化のタイミングで、ファイル名をセットする。
ホントは、ここで、フォルダーを変更したいが(変更機能がほしいが)
カレントディレクトリを対象としています。
Private Sub UserForm_Initialize()
'フォームの初期化イベントでリストボックスにデータをセットする
Dim strWORK As String
Me.ListBox1.Clear '.Clearで内容を全てクリア
strWORK = Dir("vb*.lzh") 'カレントのVB*.lzhを検索する
While strWORK <> ""
'取得したファイル名をリストに追加する、ITEMの追加
Me.ListBox1.AddItem (strWORK)
'次のファイル名を取得する
strWORK = Dir() '引数無しで呼ぶと次のファイル名がセットされる
Wend
End Sub
Public Function getFOLDER() As String
Dim objShell As Object 'Shell
Dim objFolder As Object 'Shell32.Folder
Const strTitle = "フォルダを選択してください。"
'シェルのオブジェクトを作成する
Set objShell = CreateObject("Shell.Application")
'フォルダー参照に設定
Const lngRef = &H1
'ルートフォルダーをデスクトップに設定
'5でMy Documents、6でFavoritesなど
Const fldRoot = &H0
Set objFolder = _
objShell.BrowseForFolder(0, _
strTitle, lngRef, fldRoot)
'フォルダー名を取出し、リターン値をセット
If objFolder Is Nothing Then 'キャンセルチェック
getFOLDER = "" 'リターン値に""空文字列をセット
Else
If objFolder.ParentFolder Is Nothing Then '下位を未選択デスクトップ?
Dim objWShell As Object 'WScript.Shell
'シェルのオブジェクトを作成する
Set objWShell = CreateObject("WScript.Shell")
'デスクトップの場所を返す
getFOLDER = objWShell.SpecialFolders("Desktop")
'オブジェクトの開放
Set objWShell = Nothing
Else
getFOLDER = objFolder.Items.Item.Path 'パスをセットする
End If
End If
Set objFolder = Nothing
Set objShell = Nothing
End Function
Private Sub CommandButton2_Click()
Dim strFOLDER As String '選択されたフォルダー名称
strFOLDER = getFOLDER() 'フォルダーの選択関数を呼ぶ
If strFOLDER = "" Then '選択結果がキャンセルかチェックする
Exit Sub '関数を途中で抜ける
End If
'カレントドライブ、ディレクトリを変更する
ChDrive Left(strFOLDER, 1) '頭のドライブ文字のセット
ChDir strFOLDER 'フォルダーの変更
'リストボックスの内容を変更する
'ラベルにフォルダーを表示する
Me.Label1.Caption = CurDir() & "\" 'カレントディレクトリをセットする
'フォームの初期化イベントでリストボックスにデータをセットする
Dim strWORK As String
Me.ListBox1.Clear '.Clearで内容を全てクリア
strWORK = Dir("vb*.lzh") 'カレントのVB*.lzhを検索する
While strWORK <> ""
'取得したファイル名をリストに追加する、ITEMの追加
Me.ListBox1.AddItem (strWORK)
'次のファイル名を取得する
strWORK = Dir() '引数無しで呼ぶと次のファイル名がセットされる
Wend
End Sub
処理のポイントは、
strFOLDER = getFOLDER() 'フォルダーの選択関数を呼ぶ
と、フォルダーの選択関数を呼んでフォルダーを選択させます。
If strFOLDER = "" Then '選択結果がキャンセルかチェックする
Exit Sub '関数を途中で抜ける
End If
で、フォルダー選択がキャンセルか判断して、
選択されていたら、
'カレントドライブ、ディレクトリを変更する
ChDrive Left(strFOLDER, 1) '頭のドライブ文字のセット
ChDir strFOLDER 'フォルダーの変更
と、
カレントのドライブ、ディレクトリを選択されたフォルダーに変更します。
あとは、ラベルとリストボックスに新しい値をセットします。
↑無事、フォルダーが変更されました。
-【けんぞう!】---------------------------------------------------------
ASPが利用可能なレンタルサーバーをお探しのアナタ、
http://www.ken3.org/asp/server.html ← けんぞうも使っているサーバーの紹介
『おっIISでbasp21でメール送信、mdbも使えるよ』(三流PG:31歳)
------------------------------------------------------------------------
Sub aaa()
Dim strWORK As String
'呼び出しは簡単で、調べたい文字列を渡す
strWORK = Application.GetPhonetic("三流君")
While strWORK <> ""
Debug.Print strWORK
MsgBox strWORK
'次の候補を見たいときは、引数無しで呼び出す
strWORK = Application.GetPhonetic()
Wend
End Sub
Sub bbb()
Dim y As Long
y = 1 '1行目から調べる
While Cells(y, "A") <> ""
'B列にフリガナをセットする
Cells(y, "B") = Application.GetPhonetic(Cells(y, "A"))
y = y + 1
Wend
End Sub
Private Sub WebBrowser0_BeforeNavigate2( _
ByVal pDisp As Object, _
URL As Variant, _
Flags As Variant, _
TargetFrameName As Variant, _
PostData As Variant, _
Headers As Variant, _
Cancel As Boolean)
Debug.Print "URL:" & URL
Debug.Print "FlagsL:" & Flags
Debug.Print "PostData2" & StrConv(PostData, vbUnicode)
If Len(PostData) <> 0 Then
Me![txtSENDDATA] = StrConv(PostData, vbUnicode) '送信データのチェック
End If
End Sub
Private Sub WebBrowser0_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Debug.Print URL
Debug.Print pDisp.Document.Title
Me![txtURL] = URL
Me![txtTITLE] = pDisp.Document.Title
Me![txtHTML] = pDisp.Document.all(0).innerHTML
End Sub
Private Sub WebBrowser0_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
Debug.Print "n:" & URL
Debug.Print "n:" & pDisp.Document.Title
End Sub