選択範囲のセルの数だけ、ウェブブラウザ(Firefox, Chrome)のタブを開くマクロです。
証券コードをまとめて選んで、ブラウザのタブを一気に開くために作りました。
気になる銘柄が3つあるときに、1クリックでブラウザタブを3つ開くことができます。
そのマクロのコード例と解説です。
LibreOffice Basic(リブレオフィスベーシック)で開発しました。
『選択範囲のパターン』と『コードのポイント』を紹介してから、『コード例』を載せています。
セル選択範囲のパターンは何種類?
基本的には、以下の3種類です。この記事で紹介するマクロは、これらのパターンに対応しています。
1セルだけでも検索できますし、まとめて選択した場合でも、Ctrlキーで飛び飛びの範囲を選択した場合でも検索できます。(オートフィルタ関係で少し例外があります)
セル
一番簡単なパターンです。1セル専用のマクロであれば簡単に作れます。
マクロの使い方は、セルを1つ選んで、ツールバーに登録したマクロボタンをクリック!(ブラウザが起動してタブが1つ開きます)
選択範囲
普通にまとめて選択したパターンです。
マクロボタン(SearchTwitter)をクリックすると、ブラウザが起動して5個のタブが開きます。
複数の選択範囲
『Ctrlキー(コントロールキー)』を使って、飛び飛びの範囲を選択したパターンです。
マクロボタン(SearchTwitter)をクリックすると、ブラウザが起動して6個のタブが開きます。
オートフィルタ関係の例外とは?
オートフィルタで不要な行を非表示にした状態のことです。
銘柄のスクリーニングで非表示にしたセルは、当然、選択範囲から除外したいですよね?
この記事で紹介するコードでは、選択範囲が1つの場合は不可視(ふかし)セルをスキップしてくれたのですが、Ctrlキーを使って飛び飛びに選択した場合は不可視まで拾ってしまうようでした。
おそらく、セルが『見えているか?』、『見えていないか?』の判定を追加すれば改善できると思うのですが、開発時間の関係でそこまでは作りませんでした。
マクロのコード例ってどんな感じ?
基本的には、選択範囲がセル1つだけのケースと同じです。これに、選択範囲の3つの場合分けを追加して作りました。
5つのポイント
コードのポイントは以下の5つ。
- 複数の選択範囲はどうやって取得するのか?
- セルの値はどうやって取得するのか?
- どうやって日本語URLの文字化けを防ぐのか?
- どうやってブラウザを起動するのか?
- 待機時間が必要
解説はコード例の中に書きました。
3つの関数
コードは3つの関数に分けました。以下の順番で呼び出しています。
- SearchTwitter()
※ ツールバーに登録する関数 - OpenBrowserKeywords()
※ セル選択範囲の3つの場合分けを行う関数 - OpenBrowser()
※ ブラウザを起動する関数
なぜ待機時間が必要なのか?
選択範囲のセルを待機時間ゼロでブラウザに渡していくと、以下のような現象が発生したためです。
- タブの代わりに、新しいウィンドウが立ちがってしまう。
- タブ順番が、URLを渡した順番と異なってしまう。
- ブラウザの起動エラーが発生してしまう。
特に、初回のブラウザ起動は時間がかかりますので、こういった現象が発生しやすかったです。
その対策として、待機時間を挟むことにしました。
では、どのくらい待てばいいのか?
私の環境では、1秒(1000ms)挟むと意図した通りに動いてくれました。
待機時間(ウェイト、Sleep)の作り方です。
LibreOffice Basicでは Wait() 関数で作れます。
待機時間はミリ秒で指定します。
ブラウザの起動エラーとは?
たとえば、以下のようなものです。
Mozilla Firefox, Portable Editionは、書込みできない「読取専用」エリアから起動しているようです。Mozilla Firefox, Portable Editionを一時的にPC本体のハードディスクにコピーして、そこから起動させますか?
個人情報に関する注意:あなたがYesと答えた場合、Mozilla Firefox, Portable Editionの中に有るあなたの個人データが一時的にPC本体のハードドライブにコピーされます。Mozilla Firefox, Portable Editionを閉じた時にこのデータのコピーは削除されますが、後で他の誰かがあなたのこのデータにアクセスすることができるかもしれません。
Mozilla Firefox, Portable Editionは「読取専用エリア」からは直接起動ができないので、終了します。
これらは、Firefox Quantum Portable (65.0.2 64ビット) を連続で起動しようとした時に出てきたものです。
もちろん、書き込み可能なSSDから連続起動を試みたのですが、間隔が短すぎると無理が出てしまうようでした。で、ウェイトを挟めば大丈夫でした。
コード例
以下がマクロのコード例です。
ウェブブラウザの実行ファイルパスだけ変更すれば、たぶん動くと思います。
ツールバーへの登録方法は、1セル専用のマクロの記事に画像で載せています。
うっかり大量のセルを選択して実行しちゃった時のために、上限『n_max』で止まるように作っています。上限は適当に変えてくださいませ。
REM ***** BASIC *****
'サーチツイッター関数
Sub SearchTwitter()
'ウェブブラウザの実行ファイルパスを定義
Dim browser_exe As String
'browser_exe = "F:\apps\FirefoxPortable\FirefoxPortable.exe"
browser_exe = "F:\apps\IronPortable64\IronPortable.exe"
'(※ ファイルパスは、ご自身の環境に合わせて変更してください。)
'ウェブブラウザの引数(ひきすう)を定義
Dim browser_param As String
browser_param = "" '今回は使わないので空(から)文字列を設定
'ウェブサイトのURL文字列を定義
'検索キーワードの前に来る部分と後ろに来る部分で、
'2つに分けて定義しておきます。
Dim url_1 As String
Dim url_2 As String
url_1 = "https://twitter.com/search?q="
url_2 = "" '今回は使わないので空(から)文字列を設定
'ウェブブラウザで開く
OpenBrowserKeywords(browser_exe, browser_param, url_1, url_2)
End Sub
'オープンブラウザキーワーズ関数(複数セル取得 & ブラウザ起動)
Sub OpenBrowserKeywords( _
browser_exe As String, _
browser_param As String, _
url_1 As String, _
url_2 As String _
)
' 1. ドキュメントを取得
Dim o_doc As Object
o_doc = ThisComponent
' 2. セルの選択範囲を取得
Dim o As Object
o = o_doc.CurrentController.Selection
' 3. セルごとにブラウザ起動を繰り返す
' 3-1. (変数定義)
Dim a As Long 'Address(アドレス)
Dim o_ra As Object 'RangeAddress(レンジアドレス)
Dim s As Object 'Sheet(シート)
Dim r As Long 'Row(行)
Dim c As Long 'Column(列)
Dim n As Long: n = 0 'ループカウンタ
Const n_max As Long = 10 'ループ上限
Const time_wait As Long = 1000 '単位: ms
' 3-2. (選択範囲 3パターン)
If o.ImplementationName = "ScCellObj" Then
' ■ パターン1. 選択範囲が1セル(セル単体)
OpenBrowser( _
browser_exe, _
browser_param, _
url_1, _
url_2, _
o.String _
)
' パターン1 ここまで
ElseIf o.ImplementationName = "ScCellRangeObj" Then
' ■ パターン2. 選択範囲が連続したセル範囲
'(選択範囲が連続した複数セルの場合)
'『セル範囲情報』を取得
o_ra = o.RangeAddress
'(参考) o.RangeAddressの型は
'com.sun.star.table.CellRangeAddress
'中身は シート番号, 開始行, 開始列, 終了行, 終了列。
s = o_doc.Sheets(o_ra.Sheet)
For r = o_ra.StartRow To o_ra.EndRow
For c = o_ra.StartColumn To o_ra.EndColumn
v = s.getCellByPosition(c, r).String
'セルが空でなければブラウザ起動
If v <> "" Then
'ブラウザがタブを開き切るのを待つ
If n > 0 Then
Wait(time_wait)
End If
OpenBrowser( _
browser_exe, _
browser_param, _
url_1, _
url_2, _
v _
)
End If
'巡ったセルの数をカウント
n = n + 1
'既定の数に達したら
'Forループを終了する代わりに
'OpenBrowserKeywords()関数から出る
If n >= n_max Then
Exit Sub
End If
Next c
Next r
' パターン2 ここまで
ElseIf o.ImplementationName = "ScCellRangesObj" Then
' ■ パターン3. 選択したセル範囲(複数セル)が離れている
'(『Ctrlキー』を押しながら選択した場合)
'『セル範囲情報』が『選択範囲のまとまり』ごとにあるので、
'そのまとまりをFor文で取得して、セル範囲にアクセスします。
'For文で『セル選択範囲のまとまり』ごとの番号を取得
For a = 0 To UBound(o.RangeAddresses)
'『セル範囲情報』を取得
'(シート番号, 開始行, 開始列, 終了行, 終了列)
'Addresses アドレッシス Addressの複数形
o_ra = o.RangeAddresses(a)
'セルにアクセスしてブラウザを起動
s = o_doc.Sheets(o_ra.Sheet)
For r = o_ra.StartRow To o_ra.EndRow
For c = o_ra.StartColumn To o_ra.EndColumn
v = s.getCellByPosition(c, r).String
'セルが空でなければブラウザ起動
If v <> "" Then
'ブラウザがタブを開き切るのを待つ
If n > 0 Then
Wait(time_wait)
End If
OpenBrowser( _
browser_exe, _
browser_param, _
url_1, _
url_2, _
v _
)
End If
'巡ったセルの数をカウント
n = n + 1
'既定の数に達したら
'Forループを終了する代わりに
'OpenBrowserKeywords()関数から出る
If n >= n_max Then
Exit Sub
End If
Next c
Next r
Next a
' パターン3 ここまで
End If
End Sub
'オープンブラウザ関数
Sub OpenBrowser( _
browser_exe As String, _
browser_param As String, _
url_1 As String, _
url_2 As String, _
t As String _
)
'■ OpenBrowser()が受け取った変数は何か?
'browser_exe: ブラウザの実行ファイルパス
'browser_param: ブラウザに渡す引数
'url_1: 検索キーワードの前に来るURL
'url_2: 検索キーワードのうしろに来るURL
't: 検索キーワード
'■ OpenBrowser()がすることは?
'検索キーワードでURLを作って、ウェブブラウザに渡す。
'■ どうやってやるの?
' 4. テキストが文字化けしないようにエンコード ConvertToUrl()
' 5. 必要な文字列だけ取り出す Mid() Len()
' 6. URLを組み立てる 文字列連結
' 7. shell()の第3引数を組み立てる 文字列連結
' 8. ブラウザを起動 Shell()
' 4. テキストが文字化けしないようにエンコード
'(UnicodeのUTF-8エンコーディングの16進数に変換)
'(たとえば、『あ』は『%E3%81%82』になります)
'(半角スペースなら『%20』)
t = ConvertToUrl(t)
' 5. 必要な文字列だけ取り出す
'※ ConvertToUrl()は先頭に8文字の
'『file:///』をくっつけちゃうので、
'それを取り除きます。
t = Mid(t, 9, Len(t))
'9: Len("file:///") + 1
' 6. URLを組み立てる
'(検索キーワードの後ろが空(から)文字列なら省略)
'(4つの連続ダブルクオーテーション『""""』は、
'1つのダブルクオーテーションを出すためのものです)
Dim site_url As String
If url_2 = "" Then
'検索キーワードの後ろを省略
site_url = """" & url_1 & t & """"
Else
site_url = """" & url_1 & t & url_2 & """"
End If
' 7. shell()の第3引数を組み立てる
'(半角スペースで区切って連結しています)
Dim p As String
If browser_param = "" Then
p = site_url
Else
p = site_url & " " & browser_param
End If
' 8. ブラウザを起動
'(『ブラウザの実行ファイルパス』に半角空白があっても動いた)
Shell(browser_exe, 1, p, False)
'(参考) シェル関数の引数
'Shell(Pathname As String[, Windowstyle As Integer][, Param As String][, bSync])
'(参考) 第1引数はダブルクオーテーションでくくっても動いた
'Shell("""" & browser_exe & """", 1, p, False)
'(参考) Shell()のエラー処理を作りこむなら、
'『On Error』や『Resume』などの機能を使います。
'(参考) 引数をメッセージボックスに表示
'MsgBox(browser_exe)
'MsgBox(p)
End Sub