アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

('ω') < イザユケエンジニャー

ファイルをダウンロードさせる方法

画像とかMP3ファイルとかPDFとか、
そういうものにaタグでリンクを張ると普通はブラウザで表示しちゃうのですが、
表示でなくダウンロードさせたい場合。

HTML5ではaタグに「download」属性を追加するだけでOK。

<a href="ファイルパス" download="ファイル名">ダウンロード</a>

それ以外の方法を探すとやたら面倒なのばかり…。
ダウンロードさせるファイルパスが動的に決まるものを作っていたので
本当はjQueryあたりでやりたかったんですが、
面倒だったのでaタグの中身を書き換えてしまったあとに押させる流れにしました。

<a href="#" download="" id="download_link">ダウンロード</a>
// jQuery
var filename = "test.jpg";
$("#download_link").attr("href", "/files/" + filename);
$("#download_link").attr("download", filename);

追記
jQuery部分はもうちょっと突っ込んで書いた。
JS/jQueryを使って、動的に生成したURLへ遷移させる - アナログCPU:5108843109
</追記

参考文献
https://chaika.hatenablog.com/entry/2016/03/25/073203
https://qiita.com/kawasima/items/2231f607677af31234e7

Firefoxの三種の神器(アドオン)

あくまで個人的に。

Gesturefy(マウスジェスチャー

Gesturefy – Firefox 向けアドオン

マウスジェスチャーがないとストレスMAXなのでこれは神器というか必須。
以下のように設定しています。

  • →:進む
  • ←:戻る
  • ↑→↑:URLの数値を増やす
  • ↓→↓:URLの数値を減らす
  • ↓→:タブを閉じる
  • ↑:上までスクロール
  • ↓:下までスクロール
  • ←↑→↓←:再読み込み
  • 右クリックした状態で左クリック:最近閉じたタブ一覧を表示
  • 左クリックした状態で右クリック:すべてのタブ一覧を表示

Tree Tabs(タブ管理)

Tree Tabs – Firefox 向けアドオン

タブは大量に開きっぱなしで使うので管理用。
かつてはタブグループを使っていましたが、
タブ自体に影響せずフォルダ分けしたりツリー状にできたりするのが使いやすく導入。
設定画面なんかは日本語非対応だけど直感的に使えるからとりあえずOK。

「ブックマークするほどじゃないけどストックしておきたいタブ」を
一時グループに放り込んでおいたり、
逆にいつも使うので閉じないタブを常駐グループにまとめておいたりする用途。

Instapaper

Instapaper – Firefox 向けアドオン

オンラインブックマークやらあとで読む系の管理に、
かつてはてブを使っていたのをpocketに乗り換えていたのですが(Firefox標準だし)
instapaperなるサービスがあったのでさらにそちらに乗り換えました。
pocketからインポートできるので引っ越しも楽々。

アドレスバー横にでも追加ボタンを設置しておけば
はてブやpocketと同じ感覚でブックマークに放り込める。

保存した記事を探すときにpocketもはてブも単純に見づらかった。
pocketは記事にタグ付けするタイプだったけど、
タグ付けだとどうしても増えがちになるので、目当ての記事を探しにくい。
「tags」をクリックしてから目的のタグを探すというのも手順が多くていまいち。
(しかもタグ表示エリアが狭すぎてタグ自体を探すのも手間…)

instapaperはフォルダを作ってそこに入れていくタイプだし
フォルダはサイドバーに最初から表示されてて並び順も好きに変えられるので
(個人的には)めちゃくちゃ探しやすい。

正規表現の先読み・後読み

コレほんと今まで知らなかったのが残念でならない…。
これを駆使すれば無駄なコードが結構減る場面もありそう。

先読み・後読みとは

先読みは「lookahead」、後読みは「lookbehind」の和訳です。
(後読みは戻り読みと呼ばれることも)

かなりざっくりした説明をすると、
「直後にAという文字列を持つBという文字列」とか
「直前にAという文字列を持たないBという文字列」のようなマッチングができます。

どうやって使うのか

まず、書き方と意味をまとめて紹介すると以下の通り。

肯定的先読み B(?=A)  直後にAを持つB
否定的先読み B(?!A)  直後にAを持たないB
肯定的後読み (?<=A)B 直前にAを持つB
否定的後読み (?<!A)B 直前にAを持たないB

例えば、「B(?=A)」のパターンに対して
「CBA」はマッチしますが
「ABC」はマッチしません。

PHPで書くと以下のような感じですね。

preg_match("/B(?=A)/", "CBA"); // マッチする
preg_match("/B(?=A)/", "ABC"); // マッチしない

「B(?=A)」と「BA」は何が違うのか

このような単純なパターンがマッチするかどうかの判定レベルなら
先読み後読みを使わず「BA」でも問題ありません。
この書き方が役に立つのは、マッチした文字列を抽出するときになります。

「BA」でマッチングした場合はもちろん「BA」という文字列がマッチしますが、
「B(?=A)」でマッチングした場合、あくまで「Aの前にあるB」を抽出することになるので
マッチした文字列は「B」になります。

preg_match("/B(?=A)/", "CBA", $matches);
// → $matches[0] は "B"

preg_match("/BA/", "CBA", $matches);
// → $matches[0] は "BA"

もうちょっと踏み込んだ理解

このような書き方は、「^」や「$」と同じく、位置を示すものです。
例えば「(?=A)」はAという文字列の直前の位置、
「(?<=A)」はAという文字列の直後の位置というわけです。

以下のような比較をしてみると腑に落ちやすいのではないでしょうか。

$str = "abcdefg";

preg_match("/(.*)d(.*)/", $str, $matches);
// 「文字列dの前」「文字列dの後」を抽出
// → $matches[1] は「abc」、$matches[2] は「efg」

preg_match("/(.*)(?=d)(.*)/", $str, $matches);
// 「文字列dの直前の前」「文字列dの直前の後」を抽出
// → $matches[1] は「abc」、$matches[2] は「defg」

preg_match("/(.*)(?<=d)(.*)/", $str, $matches);
// 「文字列dの直後の前」「文字列dの直後の後」を抽出
// → $matches[1] は「abcd」、$matches[2] は「efg」

否定形はちょっとややこしいですが、考え方はもちろん同じで
例えば「(?!A)」はAという文字列の直前を除いたすべての位置、と理解すればOKです。

活用例

活用例1:特定の複数ワードが順不同で含まれているかどうかをチェックする

例えば「^(?=.*a)(?=.*b)」で「aとbが両方とも順不同で含まれている」というパターンになります。
これは先読み後読みがないと一発チェックは難しそう。

以前別記事で書いたので詳しくはそちらへ。
正規表現で、複数のワードが順不同で含まれているかどうかを判定する - アナログCPU:5108843109

活用例2:文字列の複雑な置換

ある文字列について、
「lookbehind」という単語の「look」だけ取り除きたいという場合の書き方。
コードはPHPでの例。

$str = "hello lookahead/lookbehind world";
$str = preg_replace("/(?<![a-zA-Z])look(?=behind[^a-zA-Z]?)/", "", $str);
// → $str は「hello lookahead/behind world」

ここでは、「lookbehind」の文字列の前にも後にも半角英字が付かない場合を
「lookbehindという単語」とみなしています。
なので、lookという文字列に対し「直前にa~z,A~Zのいずれも持たない」という後読み、
「直後にbehind(の直後には英字を含まない)という文字列を持つ」という先読みを利用し
該当する場合に空文字に置き換えています。

これを先読み後読みを使わず実装しようとすると、
置換すべき文字列の位置を求めたあと、改めてreplaceすることになるのではないでしょうか。

活用例3:HTMLタグのスクレイピング

例えば「特定のタグに挟まれたテキストのみをスクレイピングしたい」というケースで
効率よく記述できるようになるケースもあります。

$str = "<p>test</p>";
preg_match("/(?<=\<p\>).*(?=\<\/p\>)/", $str, $matches);
// → $matches[0] は "test"

ここではかなり単純な例なので、先読み後読みを使わずとも実現可能ではありますが、
複雑になればなるほど活用しやすくなるかと思います。

ちなみに:PHPにて、先読み後読みを使わず抽出する例
カッコで括ればその部分を抽出できるので、
戻り値にちょっと無駄が多いものの、この例では先読み後読みがなくてもOKです。

$str = "<p>test</p>";
preg_match("/\<p\>(.*)\<\/p\>/", $str, $matches);
// → $matches[1] は "test"

WindowsのSkype

会社でのやりとりにSkypeを使っているのですが、
最初から入っていたSkypeアプリだと、
送受信がやたらと遅れたりカスタマイズ性が悪すぎたりしてイライラ…。

ちょっと調べてみると、Windowsでは少なくとも

の3つはありそう。(for Businessはたぶん別物)

下側の2つはこちらからダウンロードできます。
Skype をダウンロード | 無料通話 | チャット アプリ

まずは試しに「Skype for Windows」を入れてみると、
最初から入っているものと大差なし…。
フォントサイズくらいは変えさせてくれ~~。

ということで、「従来のSkype」を入れるのが正解でした。
送受信の遅れはまだ様子見ですが、
ちょっと使った限りはなんともないし、
フォントサイズを変えたりEnterで送信じゃなく改行に変更できたり。

追記
この方法でインストールしたSkypeを使っていると、
近日このバージョンは使えなくなる、という旨のメッセージが出るようになりました。
試しにアップデートしてみると、おそらく「Skype for Windows」と思われるものにすり替わりました。
なんでやねん…。

取り急ぎ、「従来のSkype」は「タブレット」の「従来の Skype for Windows タブレットをダウンロード」から入手できます。
</追記

定期的に処理を行う

5分ごとにAjax通信で画面の一部を更新するとか、
時計やタイマー的な機能の実装をするとかの用途?
(上記の例ではほかに良い手段もあるかもしれませんが)

意外と簡単に実装できました。

setInterval(function(){
    // 処理
},[ミリ秒]);

例えば以下のコードだと、
1分ごと(=60000ミリ秒ごと)にコンソールに「a」と出力します。

setInterval(function(){
    console.log("a");
},60000);

追記
途中で止めるには「clearInterval」を使用します。

var i = 0;
var timer = setInterval(function(){
    console.log("a");

    i ++;
    if (i >= 5){
        clearInterval(timer);
    }
},60000);

</追記

ExcelVBA入門 #12:繰り返し処理を極める

シリーズもくじはこちら
ExcelVBA入門 もくじ - アナログCPU:5108843109


以前、「For」を使った繰り返し構文について書きましたが、
ExcelVBA入門 #4:エンドレスエイトに学ぶ繰り返し処理 - アナログCPU:5108843109
実は他にも同じ処理を繰り返すための書き方があります。
今回はそれらを紹介しつつ、繰り返し処理全般の扱い方をまとめていきます。

続きを読む

ExcelVBA入門 #11:配列を使ってみる

シリーズもくじはこちら
ExcelVBA入門 もくじ - アナログCPU:5108843109

今回は「配列」について。

そもそも「配列」って何?

まず、変数ってあるじゃないですか。データを入れる箱。
ExcelVBA入門 #3:プログラミングには必須!変数ってなんぞ? - アナログCPU:5108843109
配列とは、このデータを入れる箱をたくさん並べてひとかたまりにしたもの、です。

いやー、ExcelVBAからプログラミングを始めた方は幸運ですね。
他のどの言語よりも配列が理解しやすいはずです。
だってそこのワークシート、
「データを入れる箱をたくさん並べてひとかたまりにしたもの」じゃないですか。
配列はそういうものをイメージすればとりあえずOKです。

もう一つ、ExcelVBAで幸運なことがあります。
それは「理解しなくてもOK」ということ。
大体はワークシートで代用できますからね。

ということで、配列の理解が難しければ一旦諦めて、代わりにワークシートを使いこなしてみましょう。
必要になったらもう一度チャレンジしよう、くらいのつもりで後回しにしてしまっても良いのです。
(ただし、オブジェクト類をまとめて扱いたければワークシートではつらいでしょうし、
 膨大なデータを処理するときは配列で扱った方が圧倒的に速くなります)

配列を使うとどんないいことがあるの?

複数のデータをひとつにまとめて扱える利点があります。
プログラム上で扱う「同じ種類のたくさんのデータ」や「いくつ存在するかもわからないデータ」を
ひとつの名前で扱えるようになるのです。
例えばExcelで住所録を作ろう、というとき、
1ファイルに1人…なんてやらずに、1行に1人くらいにして、複数人をまとめますよね?
そういったイメージで捉えればOKです。

ただ、まとめて扱うということは、どこに何が入っているかを意識して使う必要があります。
なんでもかんでもまとめてしまうとバグの原因になりますので、
できるだけ「わかりやすくするために使う」という意識を忘れないようにしましょう。

配列の超基本

まずは以下にサンプルプログラムを用意しました。
これは、コード中のコメントにもあるとおり、
決まったサイズの箱を用意して、値を入れて、表示するだけのプログラムです。

Public Sub ArrayTest()
    '0番~2番までの番号がついた箱を集めた「配列」を定義
    Dim lList(0 To 2) As Long

    'それぞれの箱に値を入れる
    lList(0) = 0
    lList(1) = 10
    lList(2) = 20

    'それぞれの箱を表示する
    Debug.Print lList(0)
    Debug.Print lList(1)
    Debug.Print lList(2)
End Sub

いつもの変数と、使い方はあまり変わりませんね。
定義のときは変数名の後に「何番から何番の箱を用意する」という情報を付けて、
使うときは変数名の後に「何番の箱を使う」という情報を付けてあげるだけです。

これなら値の数を増やしたいときも簡単です。

Public Sub ArrayTest()
    Dim lList(0 To 3) As Long

    lList(0) = 0
    lList(1) = 10
    lList(2) = 20
    lList(3) = 30

    Debug.Print lList(0)
    Debug.Print lList(1)
    Debug.Print lList(2)
    Debug.Print lList(3)
End Sub

え、定義部分が短くなっただけ?変数に数字を付けるだけでもいい?
これだと確かにそうですね。

ではこれならどうでしょう。

Public Sub ArrayTest()
    Dim lList(0 To 3) As Long
    Dim i As Long

    For i = 0 To 3
        lList(i) = i * 10
    Next

    For i = 0 To 3
        Debug.Print lList(i)
    Next
End Sub

繰り返し文を使うことで、簡単にまとめて処理することができるようになります。

たとえ要素が100個になっても変わりません。

Public Sub ArrayTest()
    Dim lList(0 To 99) As Long
    Dim i As Long

    For i = 0 To 99
        lList(i) = i * 10
    Next

    For i = 0 To 99
        Debug.Print lList(i)
    Next
End Sub

ワークシートっぽいと言うからには…

先述の例だと「データを一列に並べただけ」ですが、
ワークシートのように「行×列のデータ」を作ることもできます。

Public Sub TwoDimentionArrayTest()
    Dim vProfile(1 To 2, 1 To 4) As Variant '数値も文字列も扱うのでここではVariant

    '1人目のプロフィール
    vProfile(1, 1) = "鈴木太郎"
    vProfile(1, 2) = 20
    vProfile(1, 3) = "03-1111-1111"
    vProfile(1, 4) = "東京都新宿区"

    '2人目のプロフィール
    vProfile(2, 1) = "山田花子"
    vProfile(2, 2) = 25
    vProfile(2, 3) = "06-1111-1111"
    vProfile(2, 4) = "大阪府大阪市"

    Dim i As Long
    For i = 1 To 2
        Debug.Print vProfile(i, 1) & "(" & vProfile(i, 2) & ") " & vProfile(i, 3) & " " & vProfile(i, 4)
    Next
End Sub

ちなみに上記の結果はこんな表示になります。

鈴木太郎(20) 03-1111-1111 東京都新宿区
山田花子(25) 06-1111-1111 大阪府大阪市

これを二次元配列と呼びますが、三次元以上も可能です。
とはいえ、あまり多次元なものを使う機会はそうそうないと思いますし
わかりにくいコードにもなりがちなので、参考程度に留めておいてください。
(あまり増やしすぎるとメモリオーバーとなってしまいます)

'四次元配列の例
Public Sub FourDimentionArrayTest()
    Dim lList(0 To 1, 0 To 1, 0 To 1, 0 To 1)

    lList(0, 0, 0, 0) = 1
    lList(0, 0, 0, 1) = 2
End Sub

定義の書き方、長くない?

サイズ指定するときに、箱の最大番号だけを書く方法もあります。

Dim lList(1) As Long

「0 To」が省略されているとみなされるので、この場合は「0 to 1」、つまり2つの要素を持つ配列になります。
配列のサイズ指定(「2個の箱を作りたいから2!」とか)ではないことに注意してください。

そもそも、最初にサイズ指定しなきゃいけないの? 途中でサイズも変えたいし…

はい、ここまでが基本でしたが、実際にコードを書く時には
「最初はサイズがわからない」「途中でサイズを変えたい」というケースが大半だと思います。
当然これらに対応した書き方があります。

まず、最初の定義ではサイズを指定しません。

Dim lList() As Long

ただし、そのまま使おうとするとエラーになってしまいます。
箱がいくつあるかも分からないのに値を入れようとしたり使おうとしたりすることはできないのです。

そこでReDimの出番です。

Dim lList() As Long
ReDim lList(0 To 1)

これで、「Dim lList(0 To 1) As Long」したのと同じように、2個の箱が入った配列になります。
あとの使い方は同じ。

同じ要領で、途中でサイズを変更することもできます。
ただし、既に配列にデータが入っていてそれを維持したい場合は「ReDim Preserve」としましょう。
「ReDim」だけだと中身がクリアされてしまいます。

Dim lList() As Long
ReDim lList(2)
lList(0) = 1
ReDim lList(3) '「lList(0)」にセットした値が消える
lList(0) = 1
ReDim Preserve lList(4) '「lList(0)」にセットした値が消えない

でも、途中でサイズを変更したいときって、
往々にして「3つに増やしたい!」じゃなくて
「今いくつか知らないけど1つ増やしたい!」というパターンなんですよね。

そういうときは、今の最大値を調べるUBound関数を併用します。
まずはUBound関数単体で動かしてみましょう。ついでに似た関数であるLBoundも。

Public Sub BoundTest()
    Dim lNum(2 To 5) As Long
    Debug.Print UBound(lNum) '5
    Debug.Print LBound(lNum) '2

2番の箱~5番の箱の4つがある配列に対して使ってみると、
UBoundは「5」、最小値を調べるLBoundは「2」を返してくれます。
(この2つを組み合わせると、箱の数もわかりますね)

これを利用して、「配列をひとつ大きくする」が簡単にできます。

Public Sub ChangeArraySizeTest()
    Dim lNum() As Long
    Dim i As Long

    '配列のサイズを定義(0 To 0)
    ReDim lNum(0)
    '配列のサイズを1つずつ増やす
    For i = 1 To 4
        '「UBound(lNum) + 1」で現在の最大値+1を表すので、それを用いて再定義
        ReDim Preserve lNum(UBound(lNum) + 1)
    Next
End Sub

ReDimについてはもっと細かい話もいろいろありますが、
詳細を書くとめちゃくちゃ長くなってしまったので別の記事に起こしました。
もっと詳しく知りたい方はどうぞ。

配列のサイズが既に決まっているかどうかを知りたいんだけど…

先ほどの「配列をひとつ大きくする」サンプルプログラムでは、
ループの前に一度ReDimで定義しています。
どうしてこういうことをしているかというと、この行がないとエラーになってしまうのです。

でも本来なら先にReDimしたくない、というパターンは多くあります。
「定義されていなければ要素を1つで定義して、定義されているなら+1したい」と思うのですが、
定義されているかどうかを調べる方法は、実は確立されていません。

ググってみると、「判定はできないので、きちんとしたエラー処理を入れる」や
「Sgn関数で代用する」「Not Not 配列名」などの方法が主に出てきます。
(個人的にSgn関数で代用するのはおすすめしません。本来の目的と違いすぎる…)

一番きれいなのは、きちんとしたエラー処理を用いたチェック関数を自作してしまうことかなと思います。
(todo:そのうち作って記事にしておきます…)

参考:
VBAの動的配列で要素を宣言する前の状態をチェックする方法 | アイビースター
動的配列がReDimされたか判定(Filter関数で上限要素を-1に初期化する) - ×××Diary
VBAで配列のNull判定にSgn関数を使ってはいけない

おしまい

正直なところ、簡単なプログラムを作っているうちは配列が必要になるケースは少ないと思います。
せっかくExcelを使っているのですし、無理せずワークシートを利用した方がスマートに済む場合も多いです。
(他言語で配列を使いこなせている人は逆にワークシート利用のほうが難しいかもしれませんが…)
こういうものもある、と頭の隅に留めておいて、いざというときに見直してみるくらいでいかがでしょうか。

参考文献:
VBAの配列まとめ(静的配列、動的配列)|VBA技術解説
ReDim ステートメント
【VBA入門】配列の初期化(ReDim、Preserve、Array、Erase) | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト
VBAで定義可能な配列の最大次元数 | Excel作業をVBAで効率化

ReDimで配列サイズを再定義するための6つの掟

キャッチーなタイトルにしようとして失敗した感


PHPなんかに慣れちゃうと正直めちゃくちゃめんどくさく感じてくるVBAの配列。
中でも一番つらいのがReDim周辺。

特にシビアな処理でもない限り
「大き目のサイズを最初に指定しておけばいいか…」とかやっちゃうことも多いのでは(自分だけ?)

そんな自分のためにもReDimについてまとめなおしてみました。

ReDimの掟その1:最初にサイズ指定してしまうと使えない

最初はサイズ指定は空にしておきます。

Dim lList() As Long

Variantで定義するのもアリ。

Dim vList As Variant

ReDimの掟その2:でもサイズは指定しないと使えない

ここでReDimの出番。
ReDimせずに使おうとするとエラーになります。

Dim lList() As Long
'lList(0) = 1 // これはエラーになる
ReDim lList(0 To 1)
lList(0) = 1 'これはエラーにならない

ReDimの掟その3:ReDimなら何度でも再定義できる

Dim lList() As Long
ReDim lList(1)
ReDim lList(2)
ReDim lList(3)

ReDimの掟その4:「ReDim Preserve」にしないと中身は消える

Dim lList() As Long
ReDim lList(2)
lList(0) = 1
ReDim lList(3) '「lList(0)」にセットした値が消える
lList(0) = 1
ReDim Preserve lList(4) '「lList(0)」にセットした値が消えない

正直、ReDim Preserveだけ覚えときゃいいのでは? とも思いますが、
ReDim単独も、中身をクリアしたいときなんかにたまには便利です。たまには。

ReDimの掟その5:「ReDim Preserve」では「最後の次元の最大値」しか変えられない

一番めんどくさいのがコレ。
最小値を引き上げたいということはそうそうないのでともかくとして、
二次元配列の一次元目を変更することができないのが残念。
色々と工夫してやる必要が出てくる場合もあります。
<追記>コメント欄で工夫の例をいただいておりますのでご参照ください!</追記>

Dim lList() As Long
ReDim Preserve lList(0 To 3) '最初の定義:もちろんOK
ReDim Preserve lList(0 To 2) '最大値を引き下げる:OK
ReDim Preserve lList(1 To 2) '最小値を引き上げる:NG(エラーになる!)
Dim lList() As Long
ReDim Preserve lList(1, 1) '最初の定義:もちろんOK
ReDim Preserve lList(1, 2) '最後の次元の最大値を引き上げる:OK
ReDim Preserve lList(2, 2) '最初の次元の最大値を引き上げる:NG(エラーになる!)
ReDim Preserve lList(2, 2, 2) '次元を増やす:NG(エラーになる!)

ReDimの掟その6:LBoundとUBoundが必須

がっつり配列を扱うときに多用することになるのがLBoundとUBound(特にUBound)。
LBoundは「配列が何番から始まっているか」
UBoundは「配列が何番まであるか」
が分かります。

まず、一次元配列の場合はこちら。
配列のサイズを変えたりしつつ試してみてください。

Dim lList(1 To 2) As Long
Debug.Print LBound(lList) '「1」
Debug.Print UBound(lList) '「2」

二次元配列の場合がこちら。
各関数の第2引数に「何次元目か」を渡すことで、その次元についての情報が得られます。
(省略した場合は一次元目)

Dim lList(3 To 4, 5 To 7) As Long
Debug.Print LBound(lList) '「3」
Debug.Print UBound(lList) '「4」
Debug.Print LBound(lList, 1) '「3」
Debug.Print UBound(lList, 1) '「4」
Debug.Print LBound(lList, 2) '「5」
Debug.Print UBound(lList, 2) '「7」

この2つの関数を駆使することで、
「配列サイズを1つ増やす(減らす)」などの処理ができるようになります。

簡単なサンプルプログラムを置いておきます。
フィボナッチ数列(※)を作るプログラムで、
配列サイズを増やす、前の要素にアクセスする、など色々やっていますので
参考になればと思います。

※最初の二項が1で、第三項以降の項がすべて直前の二項の和になっている数列。
 つまり、1, 1, 2, 3, 5, 8, 13, ... という数列

Public Sub Fibonacci()
    Dim lNum() As Long '数列が入る配列
    Dim i As Long      'カウンタ用変数

    '最初の二項をセット
    ReDim lNum(1) 'lNum(0 To 1)と同義
    lNum(0) = 1
    lNum(1) = 1

    '数列の作成
    '100を超えたらやめる
    Do While True
        'lNumの最大値を今の最大値+1にする
        ReDim Preserve lNum(UBound(lNum) + 1)

        'lNumの最終項=ひとつ前の項+ふたつ前の項
        lNum(UBound(lNum)) = lNum(UBound(lNum) - 1) + lNum(UBound(lNum) - 2)

        'lNumの最終項が100をこえている場合は終了する
        If lNum(UBound(lNum)) > 100 Then
            Exit Do
        End If
    Loop

    '数列の表示
    For i = LBound(lNum) To UBound(lNum) 'iはlNumの初項から最終項まで
        Debug.Print lNum(i)
    Next
End Sub

改行を無視して検索・置換したいときのためのマクロ

サクラエディタでは複数行にまたがった検索が行えないため、
「一旦改行コードを別の文字列に置き換え」→「検索・置換」→「置き換えた文字列を改行コードに戻す」
という手段をとることにしました。

改行コードを別の文字列に置き換えるマクロ

CR, LF, CRLFをそれぞれ適当な文字列に置き換えます。
ここでは「@@@@@RN@@@@@」のような形に置き換えていますが、
そこはお好みと実用性で適宜いい感じに。

Dim dlm
dlm = "@@@@@"

Dim x
x = Editor.SearchNext(dlm, 34)
If Editor.GetSelectedString() <> "" Then
    MsgBox "デリミタ文字「" & dlm & "」が含まれているため、このマクロは利用できません。"
Else
    x = Editor.ReplaceAll("\r\n", dlm & "RN" & dlm, 38)
    x = Editor.ReplaceAll("\r"  , dlm & "R" & dlm , 38)
    x = Editor.ReplaceAll("\n"  , dlm & "N" & dlm , 38)
    Editor.ReDraw(0)
End If

特定文字列を改行コードに置き換えるマクロ

こちらは「@@@@@RN@@@@@」のような文字列を
対応する文字コードに置き換えています。

Dim dlm
dlm = "@@@@@"

Dim x
x = Editor.ReplaceAll(dlm & "RN" & dlm, "\r\n", 38)
x = Editor.ReplaceAll(dlm & "R" & dlm , "\r"  , 38)
x = Editor.ReplaceAll(dlm & "N" & dlm , "\n"  , 38)
Editor.ReDraw(0)

x = Editor.SearchNext(dlm, 34)
If Editor.GetSelectedString() <> "" Then
    MsgBox "デリミタ文字「" & dlm & "」が残っています。正しく処理されているか確認してください。"
End If

問題点

改行コードを特定文字に置き換えるのは(おそらく)問題ないのですが
例えば「@@@@@R@@@@@RN@@@@@R@@@@@」という文字列を改行ありの状態に戻すとき、
「\rRN\r」としてほしくても「@@@@@R\r\nR@@@@@」となります。
申し訳程度に警告が出るようにはしてありますが、処理としては完璧ではないですね。

20050225 / スピッツ

初めて行ったライブの感想文を発見したので要約して貼っておく。



SPITZ JAMBOREE TOUR ~あまったれ2005~ 前半戦
2005年2月25日(金)松山市民会館大ホール

  • 国公立大学前期試験当日だったので一緒に行ける友達がいなくて母親と。市内でよかった。
  • 開始前にはツアートラックを撮影したり(画像が行方不明)
  • 直前まで『チケット余りましたが買いませんかー』とか『誰かチケット余った人いませんかー』とかの叫び声が。
  • 後ろに並んでいた女の子たちは会話を聞く限り本州から来た中学生
  • グッズはTシャツとパンフとミラーと携帯電話の画面シートとコットンバッグを購入
  • 後ろの女の子たちは帰りの船代以外を全部グッズにつぎ込む勢い

セトリ

感想

  • アルバム別に見ると
    • 『スーベニア』から10曲
    • 『色色衣』『ハヤブサ』『インディゴ地平線』『惑星のかけら』から2曲ずつ
    • 『三日月ロック』『花鳥風月』『ハチミツ』『空の飛び方』から1曲ずつ
  • ライブ後に公開されたセトリを見ると何かの代わりに「歩き出せ、クローバー」が
  • 最初の3曲はすべて『スーベニア』から。喋りは全く無しで春の歌のイントロからスタート
  • そして最初っから暴れ気味の田村。
  • MCでは当たり障りのない普通のライブな挨拶。
    • そしてちゃんと話す内容を決めてきたらしいのに緊張のあまりど忘れするマサムネさん。
    • グダグダのまま強引に次に行く。ウケる観客。
  • さわ変わではやたらと盛り上がる観客。暴れる田村。
  • ありふれた人生のイントロ部分で機材トラブル発生
    • 始まってすぐ曲が途切れて一同無言、しばらく後にマサムネさん『……えー……機材トラブルです』。やり直し。
    • そしてよほど動揺したのか歌詞を間違えるマサムネさん。2番でも『あ~こーこーろが~』って。なんとか自然に直そうとするもバレバレ。
    • ベビフェも盛り上がる。やっぱり暴れる田村。
  • MC
    • マサムネさん『機材トラブルが起こった時、どうせなら即興で歌えば良かったね。(ギターを弾きつつ)松山にぃ~僕はぁ~来たんだぁ~♪ とか』
    • 田村『……そんなことするほどの時間なかったよね』
  • スタゲのイントロでは一部で今までと明らかに違う黄色い歓声が。あいのり勢か。
  • MC、高知~松山間の移動(前日は高知のオレンジホールでライブだった)で、満月とそれに照らされる景色がよく見えたという話。
    • やっぱり都会と違うと思ったとか、曲のネタが2つ3つできたというマサムネさん。
  • マサムネさん『じゃあ、次はちょっと古い曲で……「アパート」っていう曲を……』
    • 最後まで言う前に、スタゲを越える大歓声。何故かやたらと盛り上がる客席。
  • 曲が始まっても盛り上がりっぱなし、ここまでで一番観客がノリノリだったアパート。ハーモニカが素敵すぎる。
  • 一転してシュラフではやたらテンション落ちる観客。それまでほぼ全員立ってたのに座り始める人がちらほら。アパートで盛り上がりすぎかよ。
  • そして会いに行くよで再び大盛り上がり。テンションの変化がすごい。
  • マサムネさん『そろそろ飛ばしていきます! 駆け抜けるホワイトホースのように!……まあスピッツなんでチワワの全力疾走にしかならないと思いますが。』
    • 一同爆笑で台無し。でも『ホワイトホース』って言っちゃった時点で既になんだかスピッツ感がある。
  • そこから5曲連続。渚でエンジンをかけ、夢追いで大合唱し、8823でやっぱり一番盛り上がる。
    • 田村の暴れっぷりがほんっとうに凄い。ベースとクラッシュシンバルが心配になる。
  • 個人的にものすごく嬉しかったのが俺のすべて。通常イントロに入る前、30秒近くリズム隊オンリーのパフォーマンスが!
    • 崎ちゃんはかっこいいし田村は暴れすぎ。
  • MC
    • マサムネさん『なんだか今日は演奏してて時間が経つのが早いなぁ……(歓声)えーと、200…5年2月2…5日?…松山…市民会館? あ、違うか。……え、合ってる? 松山市民会館! ずっと忘れません!』
      • どこから突っ込めばいいのか。
  • ラストは案の定正夢。
  • 最新アルバム、つまり初登場にしてさっそくアンコールを掻っ攫っていくテイタム。観客の振りがしんどい。
  • メンバー紹介、やはり田村はカレーの話、崎ちゃんは動物の話。
    • 崎ちゃん、砥部動物園に遊びにきてくれていたらしい
  • そしてラストのラストはチェリー。個人的にはこの2曲がアンコールだったのは最高だった。
  • どこのMCだったか忘れたけど、テンション上がって調子に乗った田村が『これ終わったらロビーで俺のサイン会やるから!』とか適当なこと言うの好き。


1回もてっちゃんの話してないのひどいなこれ。