マクロのある暮らし(5回目) - 文字列であそぶ
こんにちは!なるーらぼです。
昨日、ノートへ投稿したあと不意にExcelが2016にアップデートされたので戸惑っておりますがVBEditorは何ら変わっていなさそうなので別の戸惑いが沸き起こっております。
さて、本日は文字列について書いていきたいと思います。
正直、スクリプト言語を使ったことがある方には面倒だなと思わせるレガシー感がありますが楽しいので使っていきましょう!
あなたと文字列、いますぐ出力
よくわからないですがいつものようにサブルーチンを用意します。
今回はすぐに出力させたいので標準モジュールに関数サブルーチンを用意します。
Function note_mu() As String
End Function
文字列を扱いたいですしイミディエイトウィンドウから実行していきますので返す型もStringにしてあります。
こうしてあれば、セルからも実行できますしね!
手始めに引数で渡された文字列になんらかの編集をして返すような関数をつくってみましょう。すこしずついきますよ。
最初は引数を渡されても何も返さない関数にしてみます。
Function note_mu(text As String) As String
note_mu = ""
End Function
これをセルから使うと何もおきません。当たり前ですが。
次はオウム返しするようにします。引数で渡された「text」をそのまま返す値にしてみます。
Function note_mu(text As String) As String
note_mu = text
End Function
するとオウム返ししてくれます。
では次は加工していきます。今度は固定の文字列を付け足して返すようにします。
Function note_mu(text As String) As String
note_mu = text & "なるーらぼです!"
End Function
文字列を結合するにはアンパサンド記号かプラス記号をつかいます。
さて、これで基本はわかりました。少し応用していきましょう。
今度は日付から曜日を返す関数にしてみます。もちろん、そんな関数を書かなくてもワークシート関数の「Text関数」を使えばできますよ。
では書いてみます。
Function note_mu(text As String) As String
Dim weekdayname As Variant
weekdayname = Array("日", "月", "火", "水", "木", "金", "土")
note_mu = weekdayname(Weekday(text) - 1)
End Function
「Weekday」関数を使うと曜日を数値で1から7のいずれかを返します。ですから用意しておいた配列の要素に日本語を当てはめておけばそれを返すことができます。
変化球
次は入力されたテキストに応じて変わったものを返してみたいと思います。
例えば、入力されたテキストの文字の数だけ「*」記号に伏せてしまうというものです。
Function note_mu(text As String) As String
note_mu = String(Len(text), "*")
End Function
これを使うと次のようになります。
いやいや・・・全部伏せてしまうと訳がわからないよ!という場合もあるでしょうから最後から4文字だけ伏せることにしましょうか。
Function note_mu(text As String) As String
note_mu = Left(text, Len(text) - 4) & String(4, "*")
End Function
うまくいきました!
でもこれ・・・4文字未満だとえらいことになる予感が。
ああ、エラーになりましたね。ではエラーになるので文字数の3割くらいが伏せられるようにしてみますか。
Function note_mu(text As String) As String
note_mu = Left(text, Len(text) - Int(Len(text) / 3)) & String(Int(Len(text) / 3), "*")
End Function
うーん、ちょっと長くなってきましたね。でもうまくいくようになったかも。
テンプレート
次はテンプレートを作ってあそんでみます。
いわゆるひな形というやつで、同じテキストなんですが特定の箇所には特定の値を入れたいな!というものです。
次のようなひな形にしてみます。
こんにちは、○○さん
なるーらぼです!
きょうはいい天気ですね。わたしは花粉症がキツイです(;_;)
では「○○」のところを与えられたテキストで入れ替えることにします。
Function note_mu(text As String) As String
Const message As String = "こんにちは、○○さん" & _
& "なるーらぼです!" & _
& "きょうはいい天気ですね。" _
& "わたしは花粉症がキツイです(;_;)"
note_mu = ""
End Function
1行が長くなりすぎるのでアンダースコア記号を使って1行を折り返して記述してあります。
それでは「○○」のところを入れ替えます。やりかたはいろいろあって、回りくどい方法から一瞬でできる方法まであります。
1.○○を切り出して入力値と結合する
2.組み込み関数を使う
一応2の方が簡単なのですが、なぜ2を使ったほうがいいかを説明するにも1で書いてみますね。
Function note_mu(text As String) As String
Const message As String = "こんにちは、○○さん" _
& "なるーらぼです!" _
& "きょうはいい天気ですね。" _
& "わたしは花粉症がキツイです(;_;)"
Dim leftmsg, rightmsg As String
leftmsg = Left(message, InStr(message, "○○") - 1)
rightmsg = Right(message, Len(message) _
- InStr(message, "○○") - 1)
note_mu = leftmsg & text & rightmsg
End Function
な・・・長い・・・
文章を右と左に分割して入力値と結合しています。そのために左から指定文字数を切り出す「Left関数」と右から同様の「Right関数」を使っています。それに「○○」がある位置を探し出すために「InStr関数」を使って何文字目なのかを割り出し、計算して切り出す長さを決めています。
ひとまず上記のテンプレートであればこれでもいいですが、2か所、3か所と増えていくとつらくありませんか??
ということで2の方法です。
Function note_mu(text As String) As String
Const message As String = "こんにちは、○○さん" _
& "なるーらぼです!" _
& "きょうはいい天気ですね。" _
& "わたしは花粉症がキツイです(;_;)"
note_mu = Replace(message, "○○", text)
End Function
い、1行になった・・・ものすごく便利ですね。
「Replace関数」は1つ目に置換対象の文字列、2つ目に置換すべき文字列、3つ目に入れ替えた後の文字列を指定します。簡単ですね。
これならテンプレートに変更を加えても軽々と入力値に入れ替えることができます。たとえば、さきほどのテンプレートに「きょう」とあるのでそのあとに日付を入れるようにしてみますか。
Function note_mu(text As String) As String
Const message As String = "こんにちは、○○さん" _
& "なるーらぼです!" _
& "きょう(▲)はいい天気ですね。" _
& "わたしは花粉症がキツイです(;_;)"
note_mu = Replace(Replace(message, "○○", text),
"▲", Format(Now, "mm月dd日"))
End Function
するとこうなります。
「Replace関数」は文字列を返します。ですから最初の「○○」を置換した後の文字列にはまだ本日の日付を置換する「▲」が残っています。そこで、連続してこれを置換すれば1行で済みます。
もちろん、何度かにわけて置換しても大丈夫ですよ。
最後に
今回は文字列であそんでみました。もっと遊んでみてもよかったなーと思いますが、今回はこれくらいにしておきます。
時間があれば数値に空文字「""」を結合して遊んでみてください。
例えばこんな感じです。
Function note_mu()
note_mu = 12 & ""
End Function
何が起きているか考えてみてください。ではまた!
この記事が気に入ったらサポートをしてみませんか?