パソコンを使い始めるときに、

ネットがおかしくないかチェックするために

インターネットの回線速度を毎回調べています。

自動的にできると良いと思い、

サイトAの方法

(BNRスピードテストの画像読み込み版をVBAのIEオブジェクトで読み取る)

を使っていましたが、

JavaScript版のほうが速度が大きめに出るので

(よい値が出た方が気分が良いので)

これの値を読み取れないか、方法を探しました。

 

サイトBのようにGNU Wgetというダウンローダーを利用する方法

もあるようですが、これは別途試すとして、

BNRスピードテストの結果が取得したい。

 

Seleniumも試しましたが、いまひとつ動作がおかしい。

使い方が悪いのかもしれませんが、すっきりしません。
 

仕方がないので、以下のような手順でごまかす(お茶を濁す)ことにしました。

 

1.BNRスピードテストを起動するマクロ(WEB起動)

2.マニュアルでスピードテストをする

3.画面のテキストを全選択し全コピー(Ctrl+A, Ctrl+C)

4.テキストデータから測定結果を抜き出すマクロ(WEBデータ取得)

 

これならあたしにでも作れます。

マクロは以下です(下のほう)。

 

マクロ「WEBデータ取得」では、

クリップボードの内容を取得して

正規表現で対象部分を抜き出して

返すようにしています。

この方法は、やり方としては全自動ではないので格好悪いですが

WEBからデータをとりあえず取得したい場合に汎用的に使えます。

 

 

 

 

 

BNRスピードテスト

 

サイトA(BNRスピードテストの画像読み込み版をVBAのIEオブジェクトで読み取る)

 

サイトB(速度測定用ツールwgetを使う)

 

 

 

 

Seleniumの使用例

 

 

 

Public Sub WEB起動()
    Dim wsh As IWshRuntimeLibrary.WshShell
    Set wsh = New IWshRuntimeLibrary.WshShell
    wsh.Run "https://www.musen-lan.com/speed/", 3
    Set wsh = Nothing
End Sub

Public Sub WEBデータ取得()
    Const Title = "測定日時,ダウンロード(Mbps),測定日時,アップロード(Mbps)"
    
    'タイトルを書く(書き直す)
    Dim buff As Variant
    buff = Split(Title, ",")
    Cells(1, 1).Resize(1, UBound(buff) - LBound(buff) + 1) = buff
    
    '最下行に今回のデータを追加する
    Dim cl As Range
    Set cl = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
    
    '測定結果を取得してシートに書き込む
    Dim result As Variant
    result = GetDataTransferSpeed
    cl.Resize(1, UBound(result) - LBound(result) + 1) = result
    Set cl = Nothing
End Sub

Private Function GetDataTransferSpeed() As Variant
    
    Const PatTitle = "BNRスピードテスト \([^\)]+\)"
    Const PatDate = "測定日時: ([0-9年月日]+)\S+\s+([0-9時分秒]+)"
    Const PatSpd = "データ転送速度:\s([0-9\.]+)Mbps"
    Dim deltaFI As Variant
    deltaFI = Array(90, 250) 'タイトルからの検出位置の差。これ以内で探す。
    
    'Webのテキストを取得する
    Dim buff As Variant
    buff = getClipboardText()
    If buff = vbNullString Then
        MsgBox "結果をクリップボードにコピーしておいてください。", vbExclamation
        Exit Function
    End If
    
    'テキストからパターンに合う部分を抜き出す
    Dim re As New RegExp, mchsTitle As MatchCollection
    Dim mchsDate As MatchCollection, mchsSpd As MatchCollection
    With re
        .Global = True
        .Pattern = PatTitle
        Set mchsTitle = .Execute(buff)
        .Pattern = PatDate
        Set mchsDate = .Execute(buff)
        .Pattern = PatSpd
        Set mchsSpd = .Execute(buff)
    End With
    
    '抜き出したデータを位置関係からダウンロードとアップロードに区別する
    Dim fiTitle(0 To 1) As Variant
    Dim DwUp(0 To 1) As Variant
    Dim DtTm(0 To 1) As Date
    Dim Spd(0 To 1) As Double
    
    
    'ダウンロードとアップロードの2か所だけが見つかる前提
    Dim i As Long, j As Long
    For i = 0 To mchsTitle.Count - 1 'データの基準になる位置を取得
        DwUp(i) = mchsTitle(i)
        fiTitle(i) = mchsTitle(i).FirstIndex
    Next
    For i = 0 To mchsTitle.Count - 1
        For j = 0 To mchsDate.Count - 1 '測定日時を取得
            If fiTitle(i) + deltaFI(0) > mchsDate(j).FirstIndex And _
                    mchsDate(j).FirstIndex > fiTitle(i) Then
                DtTm(i) = CDate(mchsDate(j).submatches(0) & " " & mchsDate(j).submatches(1))
                Exit For
            End If
        Next
        For j = 0 To mchsSpd.Count - 1 'データ転送速度を取得
            If fiTitle(i) + deltaFI(1) > mchsSpd(j).FirstIndex And _
                    mchsSpd(j).FirstIndex > fiTitle(i) Then
                Spd(i) = CDbl(mchsSpd(j).submatches(0))
                Exit For
            End If
        Next
    Next
    
    Dim result(0 To 3) As Variant
    For i = 0 To 1
        result(2 * i + 0) = DtTm(i)
        result(2 * i + 1) = Spd(i)
    Next
    
'    Dim result(0 To 1, 0 To 2) As Variant
'    For i = 0 To 1
'        result(i, 0) = DwUp(i)
'        result(i, 1) = DtTm(i)
'        result(i, 2) = Spd(i)
'    Next
    
    GetDataTransferSpeed = result
                
    Set re = Nothing
    Set mchsTitle = Nothing
    Set mchsDate = Nothing
    Set mchsSpd = Nothing
    
End Function

Function getClipboardText() As Variant
    Dim objCB As MSForms.DataObject
    Set objCB = New MSForms.DataObject
    
    Dim ClipBoardFormats As Variant, cbf As Variant
    ClipBoardFormats = Application.ClipBoardFormats
    Dim res As Variant
    res = vbNullString
    For Each cbf In ClipBoardFormats
        If cbf = xlClipboardFormatText Then
            With objCB
                .GetFromClipboard   ''クリップボードからDataObjectにデータを取得する
                res = .GetText     ''DataObjectのデータを変数に取得する
                Exit For
            End With
        End If
    Next
    getClipboardText = res
    Set objCB = Nothing
End Function