作成したエクセルファイルを、ほかの人に配布したとします。
プログラムは、バグ取りとか新しい機能の追加とかで、日々更新されます。
しかし、そのままだと配布したファイルは更新されません。
配布した相手が隣の席の人なら、新しいのをその都度提供すればそれでよいのですが、ほかの会社の人だとか、日常的に顔を合わせることのない人だと、そうはいきません。
そんな時に、ネット上からいつでも最新バージョンをダウンロードできるようにしておくと安心。
たとえば、示し合わせた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
このために、ふたつ準備が必要です。
フォーム 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 仕様のためかどうか、うまくいったりいかなかったり、挙句の果てに頻繁にエクセルが落ちてしまう目に会うようになったので、諦めました。
ちょっとややこしくなったので、全体の構成を図にまとめておきます。
