category name  »  page title date

Webからのアップデート

最新バージョンをダウンロードしてもらう

作成したエクセルファイルを、ほかの人に配布したとします。
プログラムは、バグ取りとか新しい機能の追加とかで、日々更新されます。
しかし、そのままだと配布したファイルは更新されません。
配布した相手が隣の席の人なら、新しいのをその都度提供すればそれでよいのですが、ほかの会社の人だとか、日常的に顔を合わせることのない人だと、そうはいきません。
そんな時に、ネット上からいつでも最新バージョンをダウンロードできるようにしておくと安心。

たとえば、示し合わせたURLにアクセスしてもらって、自分のバージョンと異なったバージョンが最新ということに気づいたら、ボタンを押してダウンロードしてもらう、というようなことになります。
こんな感じの画面で。

画面上のボタンをクリックすると、「ダウンロード」フォルダに最新バージョンのファイルがダウンロードされるわけです。ちなみに、この画面のHTMLは、こういう風になっています。"xxxxxxxx.xlsm"という部分をダウンロードしてもらいたいファイル名にし、同じディレクトリにアップロードしておきます。

downloadNewVersion.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <!-- あ -->
    <title>DownLoad</title>
    <meta name="description" content="新しいバージョンのダウンロード">
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <style>
        *{font-family:  "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro",Osaka, "メイリオ", Meiryo, "MS Pゴシック", "MS PGothic", sans-serif;color:#444;
margin:0;padding:0;border:none;position:relative;list-style:none;}
        body{margin: 16px 30px 0 20px;background-color:#f0f0f0;width:600px;}
        h1{margin: -6px 0 20px 30px;font-weight:bold;font-size:20px;}
        p.title{margin-bottom:20px;}
        div.buttonBox{margin:40px 0 0 40px;}
        img.button{float:left;width:100px;}
        p.buttonTitle{margin-left:120px;font-weight:bold;}
        p.buttonCaption{margin-left:140px;font-size:80%;}
    </style>
</head>
<body>
    <h1>最新バージョンのダウンロード</h1>
    <p class="title">
最新バージョンのダウンロードを行うには、下のボタンをクリックしてください。
    </p>
    <div class="buttonBox">
        <a href="xxxxxxxx.xlsm">
            <img class="button" src="downLoad.png">
        </a>
        <p class="buttonTitle">最新バージョンのダウンロード</p>
        <p class="buttonCaption">
現在の最新バージョンの番号は、<b>1.0.2</b> です。<br>
マクロの実行がブロックされた場合は、一度終了させた後、ファイルを右クリックしてプロパティを表示し、[全般]タブの最下部のブロック解除チェックボックスにチェックをいれてください。<br>
それから再起動させれば、正常に動作します。
        </p>
    </div>
</body>
</html>

URLを示し合わせるというのもストレスのもとなので、ついでにもとのエクセルからこのページにアクセスするためのマクロを追加しておきましょう。どこか適当な場所にボタンを配置しておいて、そのボタンにマクロ ShowDownLoadPage を登録しておくと便利です。
URLは、仮に"https://castfactory.org/downloadNewVersion.html"としています。

標準モジュール      ShowDownLoadPage()

Private Const downloadPageURL = "https://castfactory.org/downloadNewVersion.html"
Public Sub ShowDownLoadPage()
    CreateObject("Wscript.Shell").Run downloadPageURL
End Sub

ときどきこのマクロを実行して、最新バージョンが用意されているかどうかをチェックし、必要ならダウンロードするという手はずになります。
しかし、これも考えてみればあまりスマートとはいえません。

最新バージョンがあるかどうかを検証する

そこで、エクセルのファイルを起動すると、新しいバージョンがあるかどうかをチェックして、あればダウンロードを促すということを考えてみました。
新しいバージョン番号は、サーバー上のファイル(ここでは仮に "https://castfactory.org/version.txt" としています)に記載しておいて、それと自身のバージョン番号を照合する、という手順です。

起動した際に呼ぶのに使うのは、次のようなマクロです。

Microsoft Excel Objects ThisWorkbook

Private Sub Workbook_Open()
    CheckVersion
End Sub

このために、ふたつ準備が必要です。

ひとつは、この例では "WORK"(作業用という意味のつもり) というワークシートを用意して、その中の適当な場所に二つのセルを選び、それぞれ "LatestVersion" "CurrentVersion"という名前をつけておくこと。
LatestVersion には、サーバーから取得した最新のバージョン番号が格納されます。CurrentVersion には、現在のファイルのバージョン番号をあらかじめ記載しておきます。



もうひとつは、ダウンロードを促すためのユーザーフォームを作成しておくことです。ユーザーフォームの名前は、"CheckVersiForm" としました。マクロから使用するコントロールには、図のような名前をつけておきます。
LatestVersionLabel、CurrentVersionLabel には、それぞれワークシートWORK上のバージョン番号がコピーされます。

フォーム      CheckVersiForm

Private Sub downLoadImage_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    ShowDownLoadPage
    Unload Me
End Sub

Private Sub laterImage_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Unload Me
End Sub

downloadImage がクリックされると、先の ShowDownLoadPage が呼ばれて、downloadNewVersion.html が表示されます。

以上の準備をして、次の CheckVersion() を Workbook_Open() から呼ぶことになります。
ここでやっていることは、最新と現在のバージョンが異なっていれば、CheckVersiForm を表示してダウンロードを促す、というだけのことです。このために、getLatestVersion() で最新のバージョン番号を latestVersionURL(ここでは "https://castfactory.org/version.txt")から読みだしています。

標準モジュール    CheckVersion()

Private Const targetSheet = "WORK"
Private Const latestCell = "LatestVersion"
Private Const currentCell = "CurrentVersion"
Private Const latestVersionURL = "https://castfactory.org/version.txt"

'----- 新しいバージョンがあれば、確認フォームを表示する
Public Sub CheckVersion()
Dim latestVersion, currentVersion
      currentVersion = CStr(Range(currentCell).value)
      latestVersion = getLatestVersion
      If currentVersion = latestVersion Then Exit Sub
      With CheckVersiForm
            .Caption = "新しいバージョンがあります"
            .LatestVersionLabel.Caption = latestVersion
            .CurrentVersionLabel.Caption = currentVersion
            .Show vbModal
      End With
End Sub

'----- 最新バージョンの番号をサーバーから取得する
Private Function getLatestVersion()
Dim target
      Set target = Worksheets(targetSheet).Range(latestCell)
      target.ClearContents
      With target.Worksheet.QueryTables.Add( _
                  Connection:="URL;" & latestVersionURL, _
                  Destination:=target)
            .Refresh BackgroundQuery:=False
            .delete
      End With
      getLatestVersion = CStr(Trim(target))
End Function

サーバー上のファイルを読むのには、いろいろな手法があるようですが、ここでは QueryTables を使用しました。目的外使用みたいなものですが、安定しています。
当初は WebBrowser コントロールを使ってエレメントを取得しようとしたのですが、IE7 仕様のためかどうか、うまくいったりいかなかったり、挙句の果てに頻繁にエクセルが落ちてしまう目に会うようになったので、諦めました。

全体の構成

ちょっとややこしくなったので、全体の構成を図にまとめておきます。