FizzBuzzで覚えるVBA(いろんなFizzBuzzを紹介するよ)
こんにちは。
派犬事務員のコロです。
FizzBuzzにハマるウサ子
2回目の講座の宿題FizzBuzzにウサ子がドハマりして、毎日のようにいろんなFizzBuzzが送り付けられてきたので、変なの優秀なのを紹介します~。
FizzBuzzとはプログラミングの練習問題のこれ↓
数字を1から順に100までデバッグ出力します。
ただし
・数字が3の倍数のときには数字の代わりに「Fizz」
・数字が5の倍数のときには数字の代わりに「Buzz」
・数字が3の倍数かつ5の倍数のときには代わりに「FizzBuzz」
と出力するようにしてください。
多分全部で20~30個あったと思う。
新しい構文が出てくるたびにFizzBuzzが送られてきて、ウサ子曰く「FizzBuzzでVBAを覚えた」らしい。
VBAを勉強してるけど「なかなか使うところがない」という人はいろんなFizzBuzzを考えてみよう。
回答1(足し算バージョン)
習得できると思われるスキル
①ループ
②If文
へんてこレベル:★
Sub FizzBuzz1() Dim x As Long: x = 3 Dim y As Long: y = 5 Dim z As Long: z = x * y Dim i As Long For i = 1 To 100 If i = z Then Debug.Print "FizzBuzz" x = x + 3 y = y + 5 z = z + 15 ElseIf i = y Then Debug.Print "Buzz" y = y + 5 ElseIf i = x Then Debug.Print "Fizz" x = x + 3 Else Debug.Print i End If Next i End Sub
おお!Modを使わないタイプ!
全部足し算で考える。
回答2(ブール比較バージョン)
習得できると思われるスキル
①If文(Trueのとき処理を行う)
へんてこレベル:★
Sub FizzBuzz2() Dim x As Boolean Dim y As Boolean Dim z As Boolean Dim i As Long For i = 1 To 100 x = i Mod 3 = 0 y = i Mod 5 = 0 z = i Mod 15 = 0 If z = True Then Debug.Print "FizzBuzz" ElseIf y = True Then Debug.Print "Buzz" ElseIf x = True Then Debug.Print "Fizz" Else Debug.Print i End If Next i End Sub
「IF 式 Then」の式がTrueのとき処理を行う、とういうのを理解していて良い。
「 If z = True Then」は、zはTrueなので「 If z Then」と書くのがスマートかも。
回答3(周期バージョン)
習得できると思われるスキル
①Select Case文
Select Case文の優れているところは、Orで繋ぐ条件式が複数の場合はカンマ「,」で繋げて書けるトコ。
へんてこレベル:★
Sub FizzBuzz3() Dim i As Long Dim cnt As Long Dim loopcnt As Long For i = 1 To 100 cnt = cnt + 1 Select Case cnt Case 3, 6, 9, 12 Debug.Print "Fizz" Case 5, 10 Debug.Print "Buzz" Case 15 Debug.Print "FizzBuzz" cnt = 0 loopcnt = loopcnt + 1 Case Else Debug.Print cnt + 15 * loopcnt End Select Next i End Sub
考え方は、15で一周期。
回答4(掛け算バージョン)
習得できると思われるスキル
①四則演算?
へんてこレベル:★★
Sub FizzBuzz4() Dim x As Long, y As Long, z As Long x = 3 y = 5 z = x * y Dim ch1 As Long, ch2 As Long, ch3 As Long ch1 = 1 ch2 = 1 ch3 = 1 Dim i As Long For i = 1 To 100 If i = z * ch1 Then Debug.Print "FizzBuzz" ch1 = ch1 + 1 ch2 = ch2 + 1 ch3 = ch3 + 1 ElseIf i = y * ch2 Then Debug.Print "Buzz" ch2 = ch2 + 1 ElseIf i = x * ch3 Then Debug.Print "Fizz" ch3 = ch3 + 1 Else Debug.Print i End If Next i End Sub
掛ける数を増やすのか。なるほど。
回答5(文字列バージョン)
習得できると思われるスキル
①型の変換
へんてこレベル:★★★★★★★★★★
数値を文字列にして判定する。
Sub FizzBuzz5() Dim i As Long Dim stri As String For i = 1 To 100 'iを15で割った数値を文字列に変換する stri = Cstr(Round((i / 15), 10)) If Len(stri) = 1 Then Debug.Print "FizzBuzz" ElseIf Len(stri) = 3 Then Debug.Print "Fizz" Else If Mid(stri, 3, 1) = Mid(stri, 4, 1) Then Debug.Print "Buzz" Else Debug.Print i End If End If Next i End Sub
え?っと思った人。これを見て欲しい。
A列の値を15で割ると、なんか法則があるっぽい。
A列の値が3の倍数のとき:「0.2」「0.4」など文字列にすると3文字(点も1文字になる)
A列の値が5の倍数のとき:「0.333・・」「0.666・・・」など、3文字目と4文字目が同じ値
A列の値が15の倍数のとき:「1」「2」「3」など1文字
おお!!これはなかなか思いつかない!
ちなみに
i=1のとき
stri = Cstr(i / 15)
だと「6.66666666666667E-02」となってしまうので
stri = Cstr(Round((i / 15), 10 ) )と少数以下を10桁にして指数表示にならないように工夫したらしい。
でも、なんで1/15のときだけ指数表示になるんだろう?
回答6(イベントプロシージャもどきバージョン)
習得できると思われるスキル
①Functionプロシージャ
へんてこレベル:★★★★★★★★★
「Functionプロシージャはワークシート関数としても使えますよ。」とは言ったけど、こんなのを作るとは!
↓
「はい、入れました」
↓
「イミディエイトウインドウを見るのね?」
えっ!!イベントプロシージャ?
と思ったらFunction関数!
Function StartFizzBuzz(ByVal x As String) As String If x <> "" Then Call FizzBuzz StartFizzBuzz = "イミディエイトウィンドウを見てね" Else StartFizzBuzz = "A1セルに何か入れて" End If End Function '************************************************************ Sub FizzBuzz() Dim i As Long For i = 1 To 100 If i Mod 15 = 0 Then Debug.Print "FizzBuzz" ElseIf i Mod 5 = 0 Then Debug.Print "Buzz" ElseIf i Mod 3 = 0 Then Debug.Print "Fizz" Else Debug.Print i End If Next i End Sub
B1セルに自作のFuction関数を入れて、引数をA1セルにする。
A1セルに値が入ってる場合はイミディエイトウインドウにFizzBuzzを出力する、という仕組み。
なんか簡易イベントプロシージャって感じ。すごい!
めちゃめちゃびっくり!
回答8(足し算しばりバージョン)
へんてこレベル:★★★★
Sub FizzBuzz8() Dim i As Long Dim num1 As Long Dim num2 As Long Dim num3 As Long Dim num4 As Long num1 = 3 num2 = num1 + 3 num3 = num2 + 3 num4 = num3 + 3 Dim num5 As Long Dim num6 As Long Dim num7 As Long num5 = 5 num6 = num5 + 5 num7 = num6 + 5 Dim x As Long x = 15 For i = 1 To 100 If i = num7 Then Debug.Print "FixxBuzz" num7 = num7 + x ElseIf i = num6 Then Debug.Print "Buzz" num6 = num6 + x ElseIf i = num5 Then Debug.Print "Buzz" num5 = num5 + x ElseIf i = num4 Then Debug.Print "Fizz" num4 = num4 + x ElseIf i = num3 Then Debug.Print "Fizz" num3 = num3 + 1 ElseIf i = num2 Then Debug.Print "Fizz" num2 = num2 + x ElseIf i = num1 Then Debug.Print "Fizz" num1 = num1 + x Else Debug.Print i End If Next i End Sub
回答9(引き算しばりバージョン)
へんてこレベル:★★★★
Sub FizzBuzz9() Dim i As Long Dim x As Long Dim y As Long Dim z As Long Dim th As Long Dim fi As Long Dim ft As Long th = 3 fi = 5 ft = 15 Dim nt As Long Dim tt As Long Dim nn As Long For i = 1 To 100 If i - ft - x = 0 Then Debug.Print "FizzBuzz" nt = 90 x = NewFizzBuzz(x, i, ft, nt) y = x z = x ElseIf i - 5 - y = 0 Then Debug.Print "Buzz" tt = 100 y = NewFizzBuzz(y, i, fi, tt) ElseIf i - 3 - z = 0 Then Debug.Print "Fizz" nn = 99 z = NewFizzBuzz(z, i, th, nn) Else Debug.Print i End If Next i End Sub '*************************************************************************************************** Function NewFizzBuzz(ByVal x As Long, ByVal i As Long, ByVal mn As Long, ByVal cn As Long) As Long Dim cnt1 As Long cnt1 = 100 Dim j As Long Dim l As Long Dim m As Long m = i If x = 0 Then For j = 1 To 100 cnt1 = cnt1 - mn If cnt1 < mn Then Exit For End If Next j j = j - 1 Else For l = 1 To 100 m = m - mn If m = 0 Then Exit For End If Next l For j = 1 To 100 cnt1 = cnt1 - mn If cnt1 < mn Then Exit For End If Next j j = j - l End If Dim k As Long For k = 1 To j cn = cn - mn Next k x = cn NewFizzBuzz = x End Function
回答10(中級バージョン)
習得できると思われるスキル
①ループでのカウンタ変数の指定数の増減
②配列
Sub FizzBuzz10() Dim arr(0 To 100) As String '配列に代入 Dim i As Long For i = 0 To 100 Step 3 arr(i) = "Fizz" Next i For i = 0 To 100 Step 5 If arr(i) = "" Then arr(i) = "Buzz" Else arr(i) = "FizzBuzz" End If Next i 'イミディエイトウインドウに出力 For i = 1 To 100 If arr(i) = "" Then Debug.Print i Else Debug.Print arr(i) End If Next i End Sub
回答11(意味不明バージョン)
Sub FizzBuzz11() Dim i As Long Dim j As Long Dim k As Long Dim l As Long k = 1 For i = 1 To 100 For j = 1 To 5 If j = 1 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 2 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 ElseIf i Mod 3 = 2 Then Debug.Print "Buzz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 3 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 4 Then For l = 1 To 3 If i = 101 Then Exit Sub Else If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 ElseIf i Mod 3 = 1 Then Debug.Print "Buzz" i = i + 1 Else Debug.Print i i = i + 1 End If End If Next l ElseIf j = 5 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "FizzBuzz" Else Debug.Print i i = i + 1 End If Next l End If Next j j = 1 Next i End Sub
他にも意味不明なのが多数。
確かにFizzBuzz楽しいけど、こんなにハマる人初めて見た・・・。
みんなの凄いFizzBuzzがあったら教えてね。
VBA講座の講師をやりました!
こんにちは。
派犬事務員のコロ子です。
お久しぶりです~。
実は、ノンプロ研VBA初心者講座の講師をさせて頂きました!
先日講座を終えて、燃え尽き症候群というか放心状態というかも抜けの殻状態だけど、これが通常運転なので日常に戻ってきました。
5月下旬に講師のお話を頂いてから、テンパり過ぎてブログところか、何も手につかず日常生活に支障をきたすレベルで怯えてました。
緊張し過ぎて夜寝れないのに、昼間は眠くて居眠りする。
小心者なのに神経図太いわけではないですよ。生命維持のための防衛機能、だと思う・・・。
The内向的な性格
しゃべるの苦手。人前で話すなんてもってのほか。超内向的な性格。
「石橋を叩いて渡る」というより「石橋を叩きすぎて壊すタイプ」なんて言われた事があるけど、どちらかというと「石橋を叩いて手を痛め、おそるおそる石橋を渡り、緊張し過ぎて固くなり、足を滑らせ石橋から落下するタイプ」だと思う。そして落下先の川で慌ててバシャバシャ泳ぎ、元来た岸にたどり着く。たまにまぐれで対岸に泳ぎ着いたときは「やればできるじゃん!」と言われたりする。
今回の講座では、高橋さんや先代の講師が作り上げた強靭な石橋は壊れるはずもないのに、ビビり過ぎて無駄に叩き、足を滑らせ橋から落ちたところに、ティーチングアシスタント(TA)から浮き輪が投げられ、「助かった~、ナイスアシストです!」という間に浮き輪ごと引っ張られ対岸に到着、という感じで無事終了しました。
どんな練習をしたか
たまたまネットの記事で「内向的な性格の人は思慮深く集中力がある」的なのを見た。内向的だけど、思慮深くないし集中力もない。これは人によると思う。
そして「内向的な人は完璧に準備をした方が良い」的な事も書いてあった。
なるほど。完璧は難しいけど、ちゃんと準備すれば少しは安心できる。
最初はスライドを見ながらしゃべる練習を繰り返し行った。
スライドを見ているときは「こうやって説明しよう」と思っていても、実際に声に出してしゃべってみると言葉が出てこない。あたまの中がぐるぐるになって無言。そのまま固まる。
語彙力が少ないのが原因なのか、日頃からしゃべり慣れていないのがいけないのか。
事前打ち合わせのときに、TAさんから「理解してもらうのが目的で、かならずしも流暢にしゃべる必要はない。」と言われちょっと楽になった。また「話すことを全部書くと良い」とアドバイス頂き、スライド50~60枚分を書き出してみたが、読んでみるとなんか変。前後繋がってないというか説明になっていない。喋るのがダメでなく、書くのもダメだった。言葉を扱う能力に問題アリ、ということか・・・。
でも、いざとなればカンニングペーパーがある、という安心感で少し落ち着いた。
書くのも話すのも苦手だけど克服した、という方、アドバイスください。
環境について
デスクトップPCと壊れそうなノートPCを所有。
ノートPCをデスクトップPCのサブモニタにしようと思ったけど、ノートPCが時々固まる・立ち上がらない、WiFiが不安定、の理由で断念。(今回断念したけど、なかなか良い方法だと思う)
www.youtube.com
モニターをもう一つ買ってデュアルモニターにしようとも思ったけど(先代講師の方はみんなデュアルモニターだった)、机が狭い→部屋が狭い→小屋が狭い、という小屋が狭いのはどうにもならないので断念。
ということで、シングルモニターで仮想デスクトップを使ってみました。
tonari-it.com
↑Windows11でもOK
デスクトップ1:講座のスライド
デスクトップ2:Excel
Slack、x(旧Twitter)は予備のノートPCまたはスマホで対応。
何とかなったけど、やっぱりモニターは2つ以上あった方がやりやすいと思う。
FizzBuzzにハマるウサ子
少ししゃべるようになったところで、ウサ子に練習相手になってもらった。ウサ子はちょっとVBAをかじったことがある程度の初心者なので絶好の練習相手だ、と思ったけど・・・。
2回目の講座の宿題のFizzBuzzにウサ子がドハマりした。
どんな問題かというと
数字を1から順に100までデバッグ出力します。
ただし
・数字が3の倍数のときには数字の代わりに「Fizz」
・数字が5の倍数のときには数字の代わりに「Buzz」
・数字が3の倍数かつ5の倍数のときには代わりに「FizzBuzz」
と出力するようにしてください。
そうそう、よくあるプログラミングの練習問題のアレですよ。
「FizzBuzz楽しー!」
とか言いながら、ものすごい勢いで2個、3個、4個と作りつづけ、毎日のようにメールが届く。
講座の練習をしようとパソコンを開くとDos攻撃のようにウサ子からの「FizzBuzz攻撃」。
練習させない気かー!!
そして顔を合わせるたびに「新しいFizzBuzz見てくれた?」とドヤ顔で聞いてくる。
意味不明なのが多いので次回ウサ子の「FizzBuzz特集」するので一緒に見てほしい。
感想
卒業LT大会(こんなの作ったよ、を発表してもらう会。卒業制作発表会)で受講生の発表が素晴らしくて感動!!!
こんなボロボロだったのに「親は無くとも子は育つ」なのか。みんなちゃんとできてて嬉しー!ありがとうございました。
それにしてもノンプロ研が偉大過ぎる。こんなコロ子が講師ですよ!!
Excelでお絵描き(ちいかわが描けるコードあるよ!)
こんにちは。
派犬事務員のコロ子です。
うさ子:最近「ちいかわ」にハマってるの~。Excelでお絵描きしてるんだ。見て!見て!
コロ子:えっ!これExcelで書いたの?
うさ子:そうだよ。図形を組み合わせて作ったの~。
な、なんと!無駄な才能!こんな事ができても何にもならないのに!
お絵描きソフトが買えないビンボーなうさ子。
ときに、ビンボーは無駄な才能を開花させるのか・・・。
うさ子の作品集
コピペで作れるよ
下のコードをコピペで、うさ子の作ったちいかわが書けるよ!
めちゃめちゃ長いのでソースコードはをクリックして表示してね。
※Excelのバージョンなどでうまく位置が合わない可能性もあるかも。
これらのコードをどうやって作ったか、というと、
Sheet1(図形があるシート)の図形をすべてループしてプロパティを取得するコードをActiveSheetに出力して作成した。
これを実行すると、ActiveSheetに下の図のようにコードが出力されるので、これをVBEエディタにコピペする。
Sub ちいかわ() Dim ws As Worksheet Set ws = ActiveSheet 'セルの色をピンク ws.Cells.Interior.Color = 10040319 'ここセルに出力されたコードをにコピペ End Sub
ちいかわとハチワレ以外も作りたかったけど、図形のフリーハンドを使っていて上手くいかず・・・。
次の機会(あるのか?)チャレンジするかも。
おまけ
MKG(味噌汁かけごはん)をもうビンボー飯と呼ばせない!
こんにちは。
派犬事務員のコロ子です。
お給料は上がらないのに、物価の上昇が骨身にしみる・・・。
うさ子:あ~、お腹すいた~。コロ子何か作って~。
コロ子:えー、何にもないよー。味噌汁かけごはんでいい?
うさ子:やだよ!そんな貧乏飯食べたくないよ!!
コロ子:うさ子だってビンボーなんだから文句言うんじゃないよ!
そもそも、なんで味噌汁かけごはんは貧乏飯とカテゴライズされ嫌われているのだろうか。
コロ子的には「たまごかけごはん」も「お茶づけ」も同系列だと思うのに、たまごかけごはんは「TKG」などと呼ばれもてはやされていたり、お茶漬けは永〇園がお茶漬けの素などを販売していて、しっかり市民権を得ている。
そうだ、味噌汁かけごはんも「MKG」と呼ばれ、貧乏飯から脱出すればいいのだ!
MKGとは
①Mostかんたんごはん
ご飯に味噌汁をかけるだけ。前日の残りで簡単にできるし、もちろんレンチンのご飯と、お湯を注ぐだけの簡易味噌汁でもOKだ。
忙しいビジネスパーソンや、時間がないときにピッタリの簡単ごはんだ。
②Modern健康的ごはん
味噌は発酵食品なので、健康的なことは間違いない。具材に野菜をたっぷり入れればさらに健康的だ。味噌汁はだいたいどんな具でも合うから素晴らしい。
味噌・出汁・具材にこだわれば、意識の高い人にもピッタリな健康ご飯だ。
この理由でMKGを食べない理由はないだろう。
みんなが堂々とMKGを食べ、日本人のソウルフードになればいいのに。
MKGアレンジ例
①TMKG
TKGとのコラボMKG
卵は味噌汁の具としてもあるので、絶対おいしいはず(未検証)
卵を溶いても、月見タイプでもご自由に!
②カレーMKG
横須賀海軍カレーは味噌が入っているらしい。
昔の海軍さんはインドのカレースパイスに近づけようと、いろいろ思考錯誤して味噌を入れたとか。
だから絶対カレーにも合うはず!(未検証)
③ 蒙古タンメン中本 辛旨味噌MKG
セブンイレブンに売っているあのカップラーメンでMKGを作ってみよう。(未検証)
麺を食べ終わった汁は捨ててはいけない。
もはや味噌汁じゃない!?ですって?
MKGはそんなケチなことはいわない。味噌味のスープならなんでもOKだ。
MKGの心は広い。
MKGの標語を募集するよー
みんな大好き国民的ごはん
マナー悪くないきちんとごはん
同じユーザーフォームを複数同時に表示させる
こんにちは。
派犬事務員のコロ子です。
前回「ユーザーフォームは作った瞬間にインスタンスが生成されてオブジェクトが使えるようになる」の記事を書いたら
「あえてインスタンスを生成することもできるよ」と教えていただいた。
ということは、同じユーザーフォームを複数同時に表示することもできるのか!?
さっそく試してみよう!
同じユーザーフォームを複数同時に表示させる
このユーザーフォームを2つ同時に表示する
Sub Test1() Dim uf1 As UserForm1 Dim uf2 As UserForm1 Set uf1 = New UserForm1 Set uf2 = New UserForm1 uf1.Show vbModeless uf1.TextBox1.Value = 100 ’←値の代入はフォーム表示の前でも後でも可 uf2.Show vbModeless uf2.TextBox1.Value = 200 uf2.Top = uf1.Top + 150 ’←フォームの位置設定はフォーム表示後に行う End Sub
おお!できた!
【解説】
UserForm1型の変数を宣言してNewでインスタンスを生成する
Sub Test1() Dim uf1 As UserForm1 Dim uf2 As UserForm1 Set uf1 = New UserForm1 Set uf2 = New UserForm1
ユーザーフォームはモードレス(vbModeless)で開く。
モードレスにしないとuf1を閉じてからでないとuf2が表示されない。
uf1.Show vbModeless
uf1とuf2が同じ位置に重ならないようにuf2を下にずらす。
uf.Show vbModeless uf.Top = FormTop
フォームの位置はフォームを表示してから設定しないとエラーになる。
TextBoxへの値の代入はフォーム表示の前でも後でも可。
ダブルクリックしたらどんどんフォームが開くのを作る
なんか楽しいのでダブルクリックしたらフォームが開くのを作ってみた。
クリックした数字をTextBox1に入れてどんどんフォームを開く。
シートモジュールに記載するコード
'2番目以降のフォームの位置。パブリック変数を用意する Public FormTop As Long 'ダブルクリックのイベント Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim uf As UserForm1 Set uf = New UserForm1 '前に作ったフォームと重ならないようにする FormTop = FormTop + 100 uf.TextBox1.Value = Target.Value uf.Show vbModeless uf.Top = FormTop End Sub
フォームモジュールに記載するコード
フォームを閉じるごとにフォームの開始位置を戻す
'ユーザーフォームを閉じるとき Private Sub UserForm_Terminate() Sheet1.FormTop = Sheet1.FormTop - 100 End Sub
VBA ユーザーフォームは作った瞬間にオブジェクトが使えるようになる!?(コロ子勘違いしていた)
こんにちは。
派犬事務員のコロ子です。
お久しぶりです。長らくブログを書いてなかったけど、やめたわけじゃないよ~。
最近仕事で変な単調作業をしていて犬小屋に帰ってからぐったり疲れてパソコンを触る元気がなかったので。
VBAを書く仕事は全然疲れないのに単調作業は本当に疲れて困るわぁ~(>_<)
ユーザーフォームについて、またまた勘違いしてました・・・。
何を勘違いしていたかというと、ユーザーフォームって作った瞬間にインスタンスが生成されてオブジェクトが使えるようになるんですね。
どーゆーことかというと、
①「ボタン1」と押すとUserForm1が表示される。
②TextBox1に数字を入力する。
③UserForm1の「OK」ボタンを押すとTextBox2にTextBox1を10倍した数字が入る。
このようなフォームの場合、
この処理のコードは下記のようになる。
「ボタン1」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン1() 'ユーザーフォームを表示する UserForm1.Show End Sub
UserForm1のOKボタンを押したときのコード(UserForm1モジュールに記載) Private Sub CommandButtonOK_Click() 'TextBox2にTextBox1×10を入力 TextBox2.Value = TextBox1.Value * 10 End Sub
ねーねー。
「ボタン1」を押してフォームが表示されるのも必要だけど、シートの数字をダブルクリックしたら、最初からその数字がTextBox1に入ってフォームが表示されるようにできる?
さらにTextBox2にも×10の値を入れといてねー。
楽勝!
できますよ~。すぐやりますね~。
簡単だよー、秒でできるよー、と下記のコードを書いたら
シートモジュールのダブルクリックイベント Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) UserForm1.Show UserForm1.TextBox1.Value = Target.Value Call UserForm1.CommandButtonOK_Click End Sub
※【注意】他のモジュールからCallするので
Private Sub CommandButtonOK_Click()
↓
Public Sub CommandButtonOK_Click()
に変更する。
あれー・・・。
UserForm1.TextBox1.Value = Target.Valueに数字が入っていない。
どーゆーことかと、ステップ実行をしてみたら
ダブルクリックのイベントの中でユーザーフォームを開くので、次の処理はユーザーフォームを閉じてからじゃないと実行できないのね。なるほど~!
でも、何か変だなぁ。ユーザーフォームを閉じているのに何でUserForm1.TextBox1.Value = Target.Valueがエラーにならないんだろう・・・?
もう1回ダブルクリックでユーザーフォームを開いてみると、
なんと!!さっきダブルクリックした値が入っているではないですか!
【1回目】
3をダブルクリックしてユーザーフォームを開く
TextBox1に値は入っていない
【2回目】
5をダブルクリックしてユーザーフォームを開く
1回目でダブルクリックした値が入っている。
【3回目】
さらに別の数字をダブルクリックしてユーザーフォームを開いてみると
2回目でダブルクリックした値が入っている。
ど、どういうこと?
何で前回の値を覚えているの?
ユーザーフォームってフォームを表示したときにインスタンスが生成されて、閉じたときに破棄されるんじゃないの???
???と思いながら、下記コードを試したてみた。
Sub Test1() UserForm1.TextBox1 = 10 End Sub
UserForm1.TextBox1 に10を入れる
Sub Test2() UserForm1.Show Debug.Print UserForm1.TextBox1.Value End Sub
UserForm1が表示される。
TextBox1 に10が入っている。
Sub Test3() Debug.Print UserForm1.TextBox1.Value End Sub
UserForm1を閉じて実行するとTextBox1は空欄。
ユーザーフォームは表示していないときもメンバーにアクセスできる。
ということは
①ユーザーフォームはVBEエディタで作った瞬間にインスタンスが生成されてオブジェクトが参照できる。
②閉じた時に値が破棄される。
ということなのね!
では、正解は
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) 'TextBox1に値をセット UserForm1.TextBox1.Value = Target.Value 'クリックイベントを呼び出す Call UserForm1.CommandButtonOK_Click 'フォームを表示 UserForm1.Show End Sub
TextBox1に値をセットして
リックイベントを呼び出して
それからフォームを表示を表示する。
またまた、長いこと勘違いしてたわぁ~。全然楽勝じゃなかったわぁ~。
ユーザーフォームは表示された時にインスタンスが生成されると思ってた。
だって「UserForm_Initialize」ってイベントがあるから。。。
ということは、ユーザーフォームのメンバーの初期値は「Initialize」イベントの中で書かなくてもOKってこと?
例えば、下記のようなシートでユーザーフォームを表示するとき
「ボタン1」を押したら、コンボボックスにB列のデータを
「ボタン2」を押したら、コンボボックスにD列のデータを
表示させたいとき
いつも「Initialize」イベントで書いていたけど、これでいいんだよね。
「ボタン1」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン1() UserForm2.ComboBox1.RowSource = Range("B6:B20").Address UserForm2.Show End Sub
「ボタン2」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン2() UserForm2.ComboBox1.RowSource = Range("D6:D20").Address UserForm2.Show End Sub
もしかして「Initialize」イベント不要?
(いやいや、場合によるから)
VBAで①②③、ABCなどの連続番号を入力する(オートフィル風)
こんにちは。
派犬事務員のコロ子です。
①②③やABCのオートフィル風を作る
先日、「①②③とかABCとかをオートフィルできる方法ないんですか?」と質問を受けた。
どうやらないっぽい。関数とかで作れるみたいだけど、毎回関数を入れるのも面倒なのでVBAで作ってみよう。
Asc関数
「Asc関数」の戻り値は 「Shift_JIS の文字コード」を利用して作成してみよう。
まずはShift_JIS の文字コードを確認してみる。
右下のタスクバーの文字を右クリックして「IMEパッド」を開く
IMEパッドの左側から「シフトJIS」を選択する。
半角英数、記号などフォルダがいっぱいある。半角英数から英文字を探してみると、「ABC・・・Z」は連続した文字コードになっている。①~⑳も連続した文字コードになっている。ということは、ループで作れる!
オートフィル風は
①まず先頭に文字を入力する。
②連続文字を入力する範囲を選択する。
③選択した範囲に連続した文字が入るようにする。
上記のコードを作成する。
Sub 選択範囲を連続番号にする() Dim ran As Range Dim buf As Long For Each ran In Selection '先頭のセルの場合 If ran = Selection(1) Then 'Acsコードに変換 buf = Asc(ran.Value) Else '文字コードに戻す buf = buf + 1 ran = Chr(buf) End If Next ran End Sub
コードができたら、どのExcelでも使えるように個人用マクロブックの「PERSONAL.XLSB」に登録する。
個人用マクロブックの作り方は↓の真ん中あたりを参考にして
https://koroko.hatenablog.com/entry/2019/09/10/211811
さらにクイックアクセスツールバーにマクロを登録する。
①ファイル→オプションより「クイックアクセスツールバー」を選択する
②マクロを選択する
③「選択範囲を連続番号にする」マクロを選択する
④追加をクリックする
⑤追加した「選択範囲を連続番号にする」マクロを選択する
⑥「変更」をクリックして好きなアイコンを選択する。
⑦「OK」をクリックする
オートフィル風の出来上がり!
もちろん、横方向にも、飛び飛びでもできるよ。
「あいうえお」の場合は「ぁあぃい、かが」など並び順が不規則なので注意!
また普通の数字もできないです。
その場合はこちらを参考に。
Sub 選択範囲を連続番号にする() Dim ran As Range Dim buf As Long '数字の場合 If IsNumeric(Selection(1).Value) Then For Each ran In Selection If ran = Selection(1) Then buf = ran.Value Else buf = buf + 1 ran = buf End If Next ran '日付の場合 ElseIf IsDate(Selection(1).Value) Then Dim mydate As Date For Each ran In Selection If ran = Selection(1) Then mydate = ran.Value Else mydate = mydate + 1 ran = mydate End If Next ran '「あいうえお」の場合(ぁあぃい、かが、など並び順が不規則なので) ElseIf InStr("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん", Selection(1).Value) Then Dim i As Long For Each ran In Selection If ran = Selection(1) Then 'Acsコードに変換 buf = Asc(ran.Value) + 1 Else Do If InStr("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん", Chr(buf)) Then ran = Chr(buf) buf = buf + 1 Exit Do Else buf = buf + 1 End If Loop End If Next ran '他(①とかAとか) Else For Each ran In Selection If ran = Selection(1) Then 'Acsコードに変換 buf = Asc(ran.Value) Else '文字コードに戻す buf = buf + 1 ran = Chr(buf) End If Next ran End If End Sub
「シフトJIS」表を見ながらオリジナルの連続番号を作ってみよう!