VBA 100本ノックNo6~10
#VBA100本ノック 6本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月24日
画像のようにA1から始まる表があります。
D列にB列×C列の計算式を入れてください。
ただし商品コードに"-"の枝番が付いている場合は計算式を入れずそのままにしてください。
例.D2にはB2×C2の計算式を入れる。D4:D5には計算式を入れない。 pic.twitter.com/6Q8reO8A39
Sub ノック6本目() Dim ws As Worksheet: Set ws = Worksheets("Sheet6") Dim i As Long For i = 2 To ws.Cells(Rows.Count, 1).End(xlUp).Row If ws.Cells(i, 1).Value Like "*-*" Then ws.Cells(i, 4).Value = "" Else ws.Cells(i, 4).Formula = "=B" & i & " * C" & i End If Next End Sub
#VBA100本ノック 7本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月25日
A列は文字列データ(表示形式が文字列)で日付が入っています。
日付とみなされる場合はB列に月末日付をmmddの形式で出力してください。
日付け以外の場合は空欄にしてください。
例.B2は「0930」と出力する。
※何をもって日付とみなすかも含めて考えてください。 pic.twitter.com/Y9hNfWJe3N
Sub ノック7本目() Dim ws As Worksheet: Set ws = Worksheets("Sheet7") Dim i As Long For i = 2 To ws.Cells(Rows.Count, 1).End(xlUp).Row Dim stDate As String stDate = ws.Cells(i, 1).Value If IsDate(stDate) Then Dim dDate As Date dDate = DateValue(stDate) ws.Cells(i, 2).NumberFormatLocal = "mmdd" ws.Cells(i, 2).Value = DateSerial(Year(dDate), Month(dDate) + 1, 1) - 1 End If Next End Sub
#VBA100本ノック 8本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月26日
「成績表」シートに5教科の成績表があります。
以下の2条件を満たした者が合格となります。
・5教科合計が350点以上
・全ての科目が50点以上
G列に、合格者に対しては「合格」と出力し、不合格は空欄にしてください。 pic.twitter.com/xchRpTzVvs
Sub ノック8本目() Dim arr As Variant: arr = Worksheets("成績表").Range("a1").CurrentRegion Dim i As Long, j As Long, Goukei() As Long For i = 2 To UBound(arr, 1) ReDim Goukei(0) For j = 2 To 6 If arr(i, j) >= 50 Then Goukei(0) = Goukei(0) + arr(i, j) End If Next If Goukei(0) >= 350 Then Worksheets("成績表").Cells(i, 7).Value = "合" End If Next End Sub
#VBA100本ノック 9本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月27日
「成績表」シートに5教科の成績とG列に合否判定があります。
「合格者」シートを新規作成し、合格者の氏名だけをA列に列挙してください。
※点数は非公開なので「合格者」シートには間違っても出力しないでください。
※何度でも実行できるようにしてください。 pic.twitter.com/TzOaMaQGBv
Sub ノック9本目() Dim ws As Worksheet For Each ws In Worksheets If ws.Name = "合格者" Then Call Pass(ws) Exit Sub End If Next ws Dim newws As Worksheet: Set newws = Worksheets.Add newws.Name = "合格者" Call Pass(newws) End Sub Sub Pass(ws As Worksheet) Dim cnt As Long, i As Long Dim arr1() As String ReDim arr1(1 To 1) As String With Worksheets("成績表") For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row If .Cells(i, 7).Value = "合" Then cnt = cnt + 1 ReDim Preserve arr1(1 To cnt) arr1(cnt) = .Cells(i, 1).Value End If Next End With ws.Cells(1, 1).Value = "合格者名" Dim j As Long For j = 1 To UBound(arr1) ws.Cells(j + 1, 1).Value = arr1(j) Next End Sub
#VBA100本ノック 10本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月28日
画像のように「受注」シートに今月の受注データがあります。
受注数が空欄かつ備考欄に「削除」または「不要」の文字が含まれている行を削除してください。
行の削除は行全体を削除してください。
サンプルでは5行目と10行目を削除
※シートは任意 pic.twitter.com/SIAlWkOFB2
Sub ノック10本目() Dim ws As Worksheet: Set ws = Worksheets("受注") Dim i As Long For i = 2 To ws.Cells(Rows.Count, 1).End(xlUp).Row If ws.Cells(i, 4).Value Like "*削除*" Or ws.Cells(i, 4).Value Like "*不要*" Then ws.Rows(i).Delete Next End Sub
振り返りと反省
所要時間2時間30分… 想定より結構かかってしまった…
- ワイルドカードLike
- NumberFormatLocal
- 新規ワークシートの指定
ここら辺に手間取ってしまい、いろいろ調べながら解決。
NumberFormatLocalを使うところを最初Format関数で処理しようとしてうまくいかなかった。ここら辺のニュアンスの違いはしっかりと理解したい(´・ω・`)
Likeはだいぶ使い方がなじんだので、今後使っていきたい。
Excel 「条件付き書式」を利用した外枠罫線・格子罫線設定の切り替え自動化
どうも、こんぺです。
今回は、先日登壇させていただいた VBA座談会にて誕生した条件付き書式の小技をまとめました。
登壇した座談会についてはこちら↓
yumeoi10nen.hatenadiary.com
外枠罫線と格子罫線の自動切換え
帳票を作るにあたり、最後見栄えを整えるときに「外枠を太線に変更」や「格子線を点線に変更」といった操作をする方、結構いるのではないでしょうか。
見栄えのために「複数の罫線を設定する」という作業は地味に面倒くさい作業だと思います。(私は面倒です…)
ですが、条件付き書式は「セルの高さが変わる書式変更はできない」仕様となっているとのこと…
そのため「条件に合わせて太線に変更する」という書式設定はできないのでした!
(座談会に参加するまで全く知りませんでした…)
しかし、使い方を工夫することで太い罫線を使いながら罫線を自動で切り替えできるようになります。
テクニックが活用できる条件
- 格子罫線とを外枠罫線を使い分ける判断をするの「キー列」の設定ができること
- 条件付き書式の設定範囲が大きくならないこと(小さくなる分には対応可)
留意事項
- 条件付き書式の範囲や条件式によってはExcelファイルの処理が重くなる可能性があります
設定手順
1.使用を想定している罫線の種類のうち、最も太い線の種類で罫線を作る
2.条件付き書式を適用するセル範囲を選択した状態で「条件付き書式」の「新しいルール」を選択する
3.「数式を使用して、書式設定するセルを決定」を選択し、数式バーに条件式を入力する
例では、「前後の支店名が同じ場合」が条件であるため、「=$(キー列番号)(先頭行番号)=$(キー列番号)(次の行番号)」(画像では=$A3=$A4)と入力
4.「書式」ボタンをクリックし、「罫線」タブで格子罫線の種類と罫線を適用する辺を選択する
例では「条件に該当するセルの下部罫線を点線に変更」するため、画像のような書式を設定
5.「OK」ボタンを2回クリックし、条件付き書式を適用する
このように、支店名を変更する(厳密にはA列の上下のセルで違う文字列になる)ことで罫線が自動で変更されるようになります。
最後に
今回のテクニックは、 VBAで罫線を引く条件を書く段階に差し掛かったときに
→ 参加者A「条件付き書式で解消できるのでは?」
→ 参加者B「そういえば条件付き書式はセルの高さが変わる書式設定を指定できない!」
→ 参加者C「条件付き書式で罫線を太くできないけど、細くはできるんじゃない?」
→ できた
という会話の中で生まれたテクニックです。
三人寄れば文殊の知恵、座談会パワーが存分に発揮された結果だと思います。
次回の座談会でも、もしかしたらこれ以上の便利テクニックが生まれるかも…
ということで次回以降のスケジュールも決まっております↓
note.com
気になる方はぜひご参加してみてください!
VBA座談会&勉強会 #VBAの悩みはVBAerに聞け 第3回、ありがとうございました
どうも、こんぺです。
昨日、TwitterVBA界隈でひっそり?話題の座談会&勉強会に登壇しました。
ことの経緯はこちら↓
yumeoi10nen.hatenadiary.com
今回はこの会に登壇に際しての感想がメインとなります。
コードについてはまた後日
今回の座談会で個人的に得られた知識、知恵
1. Eraseを使うと、動的変数は一つずつ初期化しなくてもOK
動的変数を用いてカウンターを作るときは、今まで
Dim cnt(1 to 3) as Long cnt(1)=0 cnt(2)=0 cnt(3)=0
としていましたが
Dim cnt(1 to 3) as Long Erase cnt
で済む(整数型の場合、Eraseすら不要)ということをアドバイスされました。
知らなかった…
2. IsEmpty(空白の判定)
恥ずかしながら5年間存在を知らずにいました… IS関係の関数、勉強しようと反省
3. 条件付き書式の書式設定では「セルの高さ」が変わるものは変更不可
具体的に「設定している罫線より太い罫線」 「フォント」「文字の大きさ」の変更不可。しかし、座談会内で新たなテクが開発されました
登壇して良かったこと
つよつよVBAerの方々から様々なアドバイスを直接受けられること!
独学の道を進むことが多いVBAerにとってこれほど勉強になることはありません!
ありがたや…
コーディングするにあたって今までにない考え方を吸収できる
改善を強く意識している参加者それぞれの「自分の当たり前=効率化のノウハウ」がドンドン出てくるので、登壇前と登壇後では明らかに「成長した自分」を実感します。
VBAの勉強モチベーションが爆上がりする
入念にシミュレーションしたうえで臨んだものの、想像以上に時間が経つのが早かったです。そのため、「( ^ω^)…まだまだ修行が足りん…」となります。すごく修業したい気分になります。
Let's VBA100本ノック!
とにかく、めちゃくちゃ楽しい
普段は内線や周囲の横やりが多くコーディングに集中しにくい環境にいる私にとって、周囲に望まれた中でVBAのコーディングに何時間も集中できるのはすごく贅沢な時間でした。
コーディング中は緊張や焦りもありましたが、集中していた分時間がアッという間に過ぎました。
今後登壇する方へのアドバイス
生コーディングは予習しない方が吉
頭の中でシミュレーションするのはいいですが、挙動を事前確認はオススメしません!なぜなら、スリルを味わえないから…というようなものではないです。
「失敗(バグ)を起点とした新しい視点の指摘」が減ってしまうからです。
新しい視点を得ることはものすごい成長の機会になるので、バグやエラーを恐れず挑戦してほしいです。
どんなに簡単な処理でもいいので、ひとまず一つの処理を完成させる
生コーディグは最初は緊張の頭がうまく回りません。そして時間が想像しているよりずっと少なく、だんだん焦ってきます。
ですが、一つ処理を完成させるだけで不思議と一気に安心します。安心した後は想像以上に集中しますし、とにかく一つ処理を完成させることが吉だと思います。
あっという間に時間が過ぎる
私は気づいたら1時間半経過していました。ビビります。
チャットは読めません!
チャットに目をやる余裕はほとんどなくなると思います。どうしてもチャット内容が気になる人は読み上げソフトなど検討されると良いかもしれません。
わからなかったら、ググるより質問が吉
登壇者は、コーディング中はほんとに喋ることができません!そして、チャットが盛り上がっているのかも全然わかりません!
ですが、質問をすると話題提供ができ、「盛り上がりが全然ないのでは?」という不安感はだいぶ払しょくできます。
MCが読み上げてくれた質問の応答には耳を傾けた方がお得
声に出して話題に上がっている質問への応答は聞いた方がいいです。Enumの件、詳しく聞きたかった…(話題になっていた記憶がない)
最後に
まず主催をしていただいたしゃあ 様、しゃあ 様とともにMCで盛り上げて頂いたりゅうりゅう 様、長時間にわたり本当にありがとうございました。そしてお疲れ様でした。
参加していただいた皆様も長い時間お付き合いいただき、本当にありがとうございました。
正直緊張しましたし、終わった後に実力不足も感じました。それでも、登壇前と登壇後では明らかに成長した実感と自信が持てましたしたし、何より楽しかったです!
次回以降、参加できるときはできる限り参加したいと思っております。
VBA 商の求め方 まとめ
どうも、こんぺです。
今回、割り算(除算)の「商」の求め方についてメモ程度ですがまとめます。
特にVBA上で日付を取り扱ううえで「商と余り」は頻繁に使う内容で、こちらで紹介したかったのですが、地味にボリュームができてしまい別記事にしました。
日付の扱いについては後日まとめたいと思っています。
割り算(除算)の計算結果取得の手法
VBAでロジックを構成するうえで
- 割り返した時の整数部分を取得した
- 割り返した時の少数部分を取得した
- 余りを取得したい
ということはよくあると思います。
余りは
- mod関数
を利用することが一般的だと思われますが、商を求める方法はいろいろバリエーションがあるようです。
ネットで調べると
- INT関数
- FIX関数
がよくヒットします。が、関数を使わなくても算術演算子「¥マーク(\記号)」で解決しなかったっけ?と思い比較しました。
テストコードと結果
Sub test() Dim num(6) As Double num(0) = 10 / 3 num(1) = Int(10 / 3) num(2) = Int(-10 / 3) num(3) = Fix(10 / 3) num(4) = Fix(-10 / 3) num(5) = 10 \ 3 num(6) = -10 \ 3 Debug.Print num(0) Dim i As Long For i = 1 To 3 Debug.Print num(i * 2 - 1), num(i * 2) Next End Sub
無事、Fix関数と\記号の計算結果が一致。
個人的には\記号で商を求めるのがスマートなのかな…と思っていますが、
Fix関数についてあまり詳しくなくため「\記号がふさわしくない場面」がもしかしたらあるかもしれません。
そのようなパターンがあれば、ぜひ教えて頂きたいですm(_ _)m
VBA 100本ノックNo1~5
お題と回答
#VBA100ノック 1本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月19日
「Sheet1」のA1:C5のセル範囲を、「Sheet2」のA1:C5にコピーしてください。
値も数式も書式も全てコピーしてください。
ただしSelectメソッドは使用禁止
※行高と列幅の設定はしなくて良い。
Sub ノック1本目() Sheet1.Range("A1:C5").Copy Sheet2.Range("A1").PasteSpecial End Sub
#VBA100本ノック 2本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月20日
「Sheet1」のA1:C5のセル範囲を、「Sheet2」のA1:C5にコピーしてください。
数式は消して値でコピー、書式もコピーしてください。
※書式は「セルの書式設定」で設定可能なもの(ロックは除く)。
入力規則やメモ(旧コメント)は書式ではありません。
「ふりがな」は任意で
Sub ノック2本目() Sheet1.Range("A1:C5").Copy Sheet2.Range("A1").PasteSpecial (xlPasteValuesAndNumberFormats) End Sub
#VBA100本ノック 3本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月21日
画像のように1行目に見出し、A列に№が入っています。
№の行数およびデータ行数は毎回変化します。
この表の見出し(1行目)と№(A列)を残して、データ部分のみ値を消去してください。
※シートはアクティブシート pic.twitter.com/uXrvsihbHD
Sub ノック3本目() ActiveSheet.Range(Cells(2, 2), Cells(Rows.Count, Columns.Count)).ClearContents End Sub
#VBA100本ノック 4本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月22日
画像のように1行目に見出し、A列に№が入っています。
この表範囲の一部には計算式が入っています。
(画像の最下行とD列には数式が入っています。)
データ行数は毎回変化します。
見出し行とA列№と計算式は残し、定数値だけを消去してください。
※画像ならB2:C11を消去 pic.twitter.com/kIe4Jns164
Sub ノック4本目() ActiveSheet.Range(cells(2, 2), cells(Rows.Count - 1, Columns.Count - 1)).ClearContents End Sub
#VBA100本ノック 5本目
— エクセルの神髄 (@yamaoka_ss) 2020年10月23日
画像のようにB2から始まる表があります。
B列×C列を計算した値をD列に入れ、通貨\のカンマ編集で表示してください。
ただしB列またはC列が空欄の場合は空欄表示にしてください。
例.D2にはB3×C3の計算結果の値を「\234,099」で表示、D5は空欄
※ブック・シートは任意 pic.twitter.com/zRBSVikFXL
Sub ノック5本目() With ActiveSheet Dim c As Long: c = .cells(Rows.Count, 2).End(xlUp).Row Dim i As Long For i = 3 To c If Not (.cells(i, 2).Value = "" Or .cells(i, 3).Value = "") Then .cells(i, 4).Value = .cells(i, 2).Value * .cells(i, 3).Value .cells(i, 4).NumberFormat = "\\#,##0" End If Next End With End Sub
感想と振り返り
賞味30分。
5本目について最初にFormat関数を使ってしまったことで文字列扱いになってしまい、手間取った。
基本的なもので難しい操作とかはないけど、Rangeクラスのプロパティとメソッドがうろ覚えで全然使い切れていないと実感。
精進あるのみ。
第3回 #VBAの悩みはVBAerに聞け に登壇させてもらいます!
はじめに
どうも初めまして、こんぺ と申します。
突然ですがこの度、TwitterのVBAクラスタ界隈で話題になっている「#VBAの悩みはVBAerに聞け」という勉強会に登壇させていただくことになりました!
「VBAの悩みはVBAerに聞け」とは?
こちらの勉強会は、かずやん 様(@y8bV4ty1wbkTjPd)が作った「#VBAの悩みはVBAerに聞け」のハッシュタグがきっかけとなり生まれた勉強会となっており、
しゃあ 様( @vba07529852 )が主催されてます。
#VBAの悩みはVBAerに聞け
— しゃあ@やっぱりVBAが好き (@VBA07529852) January 17, 2021
第3回開勉強会 on Zoom 催決定!
1月23日(土) 20時開宴
登壇いただくのは こんぺ(msj)さん!
5年前に作成したものと最近作成したものを2点ご紹介いただきます。https://t.co/j2Xd7ABGQC
チェケラ!
「#VBAの悩みはVBAerに聞け」というハッシュタグに関して、松田軽太 様が投稿された記事がとても分かりやすくまとめられています。
気になる方は是非ご一読ください。
また、どのようなことを過去の勉強会ではどのようなことをやったかについては、様々な方が記事にされています。こちらもぜひご一読ください。
そんなこんなで勉強会に向けてしゃあ様とやり取りする中、「勉強会で使うコードを公開してはどうでしょうか?」とご提案いただき、本ブログ記事を書いております。
「はじめてのマクロ」を作るに至った経緯
私の勤め先では、車通勤する社員に対し、会社に免許書や車検証など各証書のコピーを提出するという社内ルールがあります。
そして期限間近になると対象者に書類提出を促すための周知文書を作成する必要があり
- 提出書類ごとに期限間近の対象者を支店ごとにリストアップ
- 期限切れの社員はまとめて別項目にリストアップ
- この2つのリストを所定の様式(見た目)に加工
という至極単純なルーティーンが毎月あります。
5年前、入社したばかりでこのような簡単な業務をいろいろ振られていました。
ですが、半年後には
「この業務、面倒くさいし、ちょいちょいミスる、どうにかならんかExcelよ (´・ω・`)」
となっていました。
その時、大学講義で1度だけ触れたに「VBA」が頭をよぎり、「自動化で楽できるんじゃね?」と思い立ち… 早速参考書を購入。
参考書とインターネットにあるコードを写経、切り貼りして初めて書いたコードが下のものになります。
勉強会で用いるコード
※1 実際のコードとは一部標記を修正しています。
※2 Excelシートの画像については身バレの可能性が高くなることを憂慮し掲載しておりません。ご容赦ください。
Option Explicit Sub UpDateReport() Dim i As Long, j As Long, k As Long, l As Long, m As Long, n As Long, o As Long, p As Long, q As Long, r As Long, Check(2) As Date, Target(2) As Range, Name As Range, Namber As Range i = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row Application.ScreenUpdating = False Sheet2.Range(Cells(7, 2), Cells(38, 9)).ClearContents Sheet2.Range(Cells(43, 2), Cells(51, 9)).ClearContents Sheet2.Range(Cells(43, 2), Cells(51, 9)).Interior.ColorIndex = 2 For k = 0 To 2 l = 7 '本社先頭 m = 11 'A支店先頭 n = 19 'B支店先頭 o = 28 'C支店先頭 p = 32 'D支店先頭 q = 43 '期限切れ先頭 For j = 3 To i Check(0) = Sheet1.Cells(j, 5) '免許証期限 Check(1) = Sheet1.Cells(j, 7) '車検証期限 Check(2) = Sheet1.Cells(j, 9) '任意保険期限 Set Target(0) = Sheet1.Cells(j, 5) '免許証期限 Set Target(1) = Sheet1.Cells(j, 7) '車検証期限 Set Target(2) = Sheet1.Cells(j, 9) '任意保険期限 Set Name = Sheet1.Cells(j, 4) Set Namber = Sheet1.Cells(j, 14) If k = 0 Then If Sheet2.Cells(3, 10) > CDbl(Check(k)) Then Name.Copy Sheet2.Cells(q, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(q, 3).PasteSpecial (xlPasteValues) q = q + 1 ElseIf Sheet2.Cells(3, 11) > CDbl(Check(k)) Then If Sheet1.Cells(j, 3).Value = "本社" Then Name.Copy Sheet2.Cells(l, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 3).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "E支店" Then Name.Copy Sheet2.Cells(l, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 3).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "A支店" Then Name.Copy Sheet2.Cells(m, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(m, 3).PasteSpecial (xlPasteValues) m = m + 1 ElseIf Sheet1.Cells(j, 3).Value = "B支店" Then Name.Copy Sheet2.Cells(n, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(n, 3).PasteSpecial (xlPasteValues) n = n + 1 ElseIf Sheet1.Cells(j, 3).Value = "C支店" Then Name.Copy Sheet2.Cells(o, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(o, 3).PasteSpecial (xlPasteValues) o = o + 1 ElseIf Sheet1.Cells(j, 3).Value = "D支店" Then Name.Copy Sheet2.Cells(p, 2).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(p, 3).PasteSpecial (xlPasteValues) p = p + 1 End If End If ElseIf k = 1 Then If Sheet2.Cells(3, 10) > CDbl(Check(k)) Then Name.Copy Sheet2.Cells(q, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(q, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(q, 6).PasteSpecial (xlPasteValues) q = q + 1 ElseIf Sheet2.Cells(3, 11) > CDbl(Check(k)) Then If Sheet1.Cells(j, 3).Value = "本社" Then Name.Copy Sheet2.Cells(l, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(l, 6).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "E支店" Then Name.Copy Sheet2.Cells(l, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(l, 6).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "A支店" Then Name.Copy Sheet2.Cells(m, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(m, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(m, 6).PasteSpecial (xlPasteValues) m = m + 1 ElseIf Sheet1.Cells(j, 3).Value = "B支店" Then Name.Copy Sheet2.Cells(n, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(n, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(n, 6).PasteSpecial (xlPasteValues) n = n + 1 ElseIf Sheet1.Cells(j, 3).Value = "C支店" Then Name.Copy Sheet2.Cells(o, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(o, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(o, 6).PasteSpecial (xlPasteValues) o = o + 1 ElseIf Sheet1.Cells(j, 3).Value = "D支店" Then Name.Copy Sheet2.Cells(p, 4).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(p, 5).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(p, 6).PasteSpecial (xlPasteValues) p = p + 1 End If End If ElseIf k = 2 Then If Sheet2.Cells(3, 10) > CDbl(Check(k)) Then Name.Copy Sheet2.Cells(q, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(q, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(q, 9).PasteSpecial (xlPasteValues) q = q + 1 ElseIf Sheet2.Cells(3, 11) > CDbl(Check(k)) Then If Sheet1.Cells(j, 3).Value = "本社" Then Name.Copy Sheet2.Cells(l, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(l, 9).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "E支店" Then Name.Copy Sheet2.Cells(l, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(l, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(l, 9).PasteSpecial (xlPasteValues) l = l + 1 ElseIf Sheet1.Cells(j, 3).Value = "A支店" Then Name.Copy Sheet2.Cells(m, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(m, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(m, 9).PasteSpecial (xlPasteValues) m = m + 1 ElseIf Sheet1.Cells(j, 3).Value = "B支店" Then Name.Copy Sheet2.Cells(n, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(n, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(n, 9).PasteSpecial (xlPasteValues) n = n + 1 ElseIf Sheet1.Cells(j, 3).Value = "C支店" Then Name.Copy Sheet2.Cells(o, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(o, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(o, 9).PasteSpecial (xlPasteValues) o = o + 1 ElseIf Sheet1.Cells(j, 3).Value = "D支店" Then Name.Copy Sheet2.Cells(p, 7).PasteSpecial (xlPasteValues) Target(k).Copy Sheet2.Cells(p, 8).PasteSpecial (xlPasteValues) Namber.Copy Sheet2.Cells(p, 9).PasteSpecial (xlPasteValues) p = p + 1 End If End If End If Application.CutCopyMode = False Next Next Application.ScreenUpdating = True Application.CutCopyMode = False End Sub
その後
このコードを書き上げ、30分くらいかかっていた作業がワンクリックで終わるようになると、そこにひとりのVBAerが誕生していました。
そのVBAerはすっかり気をよくして、手の届く業務範囲で自動化を押しすすめ、身の丈に合わない依頼を引き受け盛大にズッコケたりしました。
…そんなこんなで時は5年たち、まさかのVBA勉強会に無謀にも立候補。
公開できるよう一部修正するため、5年前に自身が書いた渾身のコードを読み返すことに…
( ^ω^)・・・
無駄に長ぇなぁオイ!(# ゚Д゚)
まぁ。プログラミングの基本や作法も全然わかっていないときに書いたコードなので、いろいろとご容赦ください…
というわけで、当初の内容から少し変わって
↓ のようになりました!
第3回のイベント内容に異変が!!
— しゃあ@やっぱりVBAが好き (@VBA07529852) 2021年1月19日
なんとなんと!
リアルタイム リファクタリング!
過去作プログラムを、機能を変更せずにより洗練されたコードに再構築!
他人の生のコーディングを見られる機会なんてめったにないぞ!
Don't miss it!#VBAの悩みはVBAerに聞け https://t.co/LGTyGqZBNO
この無駄に長いコードを無謀にも生リファクタリング!
5年でいろいろズッコケたおかげでスキルアップしている…はずですが、あまり期待はしないでください…
その他話題にしたいなぁ…と漠然と思っていることは
- 今の自分がこの作業を改めて自動化するならどうするか
- 「自分で使うマクロ」と「人に使ってもらうマクロ」を組む時に考えていること
など「プログラミングの考え方」や「VBAをつかった業務改善」のことなどをメインとしてVBAerの皆様と意見交換できればいいなぁ、と考えております。
夢の先をめざせ!~PIRAMIRiSEの記憶~
12/13~14に開催されたぴらみさんこと、平山笑美さんの1thソロライブ「PIRAMIRiSE」に1日目に参加してきました。
もう一曲一曲感想を書き倒したい勢いですが、一番言いたいことがぼやけてしまうので割愛…
今回のライブは本当に夢のような時間でした。実際に翌朝はライブのことを思い出すと夢を見ていたような錯覚に陥ってましたし。。。
そんなぴらみさんの初ソロライブは本当に『ぴらみさんのために』という思いが溢れ出ていたライブだったと思います。
入場が開演ぎりぎりになってしまい最後列、スピーカーの後ろから観ていたので、ぴらみさんの歌声120%浴びることはできなかったのは正直ちょっと残念…でしたが、それでもぴらみさんの姿をはっきりと見ることができたし、なにより「フロアにいるファンの様子」も終始観ることができたのがよかったです。ぴらみさんの歌声に集中していた中で2割くらい「会場の雰囲気」を傍観していた自分がいました。さながら「ぴらみさんの生歌を聞きながら一足先にライブBDを見ていた」感覚。
自分自身そんなにライブに参加したことがないので比較できませんが、このライブは関係者のみならず、ファンの「情熱」がすごかったです。
ミリオンライブをきっかけにファンになった人が多いためか、初披露の新曲に対してもしっかりコールを入れるあたり「さすが同僚やな…」とコールし、「JUMP!」「May be,May be,May be」と「フライング・ハイ!」ではファンの気持ちが爆発してました…。
それでも「500人オールスタンディング」って会場にもかかわらず終始平和に終わったことにこのライブの「本質」を感じた気がします。
このライブは皆さんご存じの通りクラウドファンディングにより楽曲作成からライブの実現に至った経緯があります。
(↓ プロジェクトのリンク。フォローしてない人は登録、登録ぅ!)
fanbeats.jp
「ライブに行く」っていう行為は普通「ライブ会場という楽しい場所」が提供されていて、そこに「自分が楽しくなるため」「自分が気持ちよくなるため」にするという側面があると思うんです。だからというべきか、迷惑行為を禁止するアナウンスがあっても「自分が楽しければいい」というような立ち振る舞いをする観客がいるライブもあるんだと思います。
でもこのライブは成り立ちがそもそも全然違います。
無事に終わった今だからこそ言えますが、「ライブが実現できなかった」という可能性もあったんです。「ライブをしたい」という「ぴらみさんの夢」に「ぴらみさんの可能性」を見出してくれた「クリエイター・関係者の情熱」、そして「ぴらみさん自身の歌が聞きたい」という「ファンの夢」のなに一つが足りていなくても実現しなかった時間でした。「自分が楽しくなる」という気持ち以上に「ライブの実現」という一つの目標にファンも必死だったんだと思います。
そのためか、「おめでとう」「ありがとう」っていう言葉をいう機会はあったけど、その言葉の副音声に「ずっと待ってた!」「これからも応援したい」「絶対成功させる!」っていう熱い思いを一人一人乗せてた気がします。(幻聴だったらすみません)
1日目のMCでぴらみさんが噛んでしまった(かわいかったです)あと、「そっか…そうだよね、私のためにきてくれたんだもんね…」とつぶやいていましたが、この言葉が本当に嬉しかったです。
「あなたの夢が私の夢だから…」という昨今の漫画やゲームにすら出てこないような「純粋な献身」で実現した空間が荒れるはずがないです。
みんなの夢が実現したからこそ「夢のような時間」だったのかな、と夢心地から覚めてきて振り返っています。
そして!2ndアルバム作成&2ndライブ開催が決定!!やったぜ!
これからも応援し続けねば…
「夢のような時間」が終わって、ぴらみさんの未来図が描かれたからこそ、『Perfect Place』のこの歌詞で締めたいと思います。
終わることのない世界 夢の先を目指せ!