はじめてのVBA
・はじめてのVBA
・本開発までの暫定対応
↓
品質
・改修想定なし
・問題なく動く(想定通りに使った場合に限る)
構成
シート1:説明書シート。コピペボタン・CSV出力ボタンをつける
シート2:CSV出力元シート(シート3の入力値をコピペする)。セルの書式を設定する。
シート3:ユーザが入力するシート。プルダウンを作る。
■Excel
仕様上、月日は0埋め。
月日が1桁の時も日付の先頭を揃えたい
(ググったワード:"excel 日付 0埋め")
セルを右クリック > 「セルの書式設定」を選択
「表示形式」タブ > 「分類」から「ユーザー定義」を選択
パターン1
「種類」yyyy/mm/dd > 「OK」をクリック
例)セルの入力値→"2017/7/1"
表示 →"2017/07/01"
パターン2
「種類」yyyymmdd > 「OK」をクリック
例)セルの入力値→"2017/7/1"
表示 →"20170701"
複数の候補から選択する項目。
項目によって、数字が全角だったり半角だったり…。
入力よりも、選ばせた方がよさそう。
そうだ、プルダウンを作ろう。
3ステップ!Excelでプルダウンリストを作成する方法|エクセルハック
(ググったワード:"excel プルダウン")
「データ」タブ > 「データの入力規則」をクリック > 「データの入力規則」を選択
「設定」タブ > 「リスト」を選択 > 「ドロップダウン リストから選択する」にチェックを入れる > 「元の値」に候補を","区切りで入力 > 「OK」をクリック
EXCELからCSVファイルの出力方法について - Excel(エクセル) 締切済 | 教えて!goo
(ググったワード:"エクセル csv 出力 ボタン")
回答No.5のコードを参考にさせていただく。
マクロ実行でCSVが出力されることは確認できた。
これをベースにどんどん仕様を盛り込んでいく。
次に、ファイル名に設定する今日の日付の取得。
VBAで今日の日付をyyyymmdd形式で取得する-Date・Format関数:エクセルマクロ・Excel VBAの使い方-VBA関数 http://www.relief.jp/itnote/archives/excel-vba-today-yyyymmdd.php
(ググったワード:"エクセル マクロ 日付取得")
最後に、シートの入力値のコピペ。
エクセルVBA 別シートの複数のセルの値をコピーする方法 - Excel(エクセル) 解決済 | 教えて!goo
(ググったワード:"エクセル マクロ シート コピー 範囲 指定")
入力されたセルだけをコピペ範囲にしたい。
No.8 ワークシートの最終行、最終列を取得する
(ググったワード:"マクロ 最大行")
マクロ実行用のボタンをつける。
Excel マクロ実行ボタンを作ろう~やさしいマクロ講座
(ググったワード:"マクロ ボタン")
操作の説明を書いて、Excel完成。
ところが、処理にやたら時間がかかる。
処理速度の改善へ。
Office TANAKA - Excel VBA高速化テクニック[無駄な表示を止める]
Office TANAKA - Excel VBA高速化テクニック[名前で呼ぶな]
Office TANAKA - Excel VBA高速化テクニック[セルの指定方法]
Office TANAKA - Excel VBA高速化テクニック[セルを配列に入れる]
(ググったワード:"マクロ 処理 高速化")
…で、最終的にできたマクロがこんな感じ、だったような。
Sub copyInputValue() Dim sh2 As Worksheet Dim sh3 As Worksheet Dim tmp As Variant Application.ScreenUpdating = False Set sh2 = Worksheets(2) Set sh3 = Worksheets(3) maxRow = sh3.Cells(Rows.Count, 1).End(xlUp).Row maxCol = sh3.Cells(1, Columns.Count).End(xlToLeft).Column tmp = sh3.Range(sh3.Cells(2, 1), sh3.Cells(maxRow, maxCol)) sh2.Range(sh2.Cells(2, 1), sh2.Cells(maxRow, maxCol)) = tmp Application.ScreenUpdating = True End Sub Sub outputCsv() Application.DisplayAlerts = False Application.ScreenUpdating = False main_f = ActiveWindow.Caption out_pass = ActiveWorkbook.Path & "\" Sheets(2).Select Sheets(2).Copy ActiveWorkbook.SaveAs Filename:= _ out_pass & Format(Date, "yyyymmdd") & ".csv", _ FileFormat:= xlCSV, CreateBackup:= False ActiveWindow.Close Application.ScreenUpdating = True Application.DisplayAlerts = True End Sub
もうひとつマクロ作ってたような気がするけど、忘れた。
finalなListでaddできちゃう問題
とあるコードが数字→英数字になる仕様変更に取り組んだときの、気づきと備忘録、その2。
正規表現は満たしていても、NGにするコードが、仕様としていくつか含まれている。
その仕様を含んだ実装。
final List<String> NG_CODE_LIST = new ArrayList<String>(); { NG_CODE_LIST.add("000"); NG_CODE_LIST.add("999"); } if(targetCode.matches("^[0-9a-zA-Z]{3}+$") && !NG_CODE_LIST.contains(targetCode)) { // コードのチェック仕様を満たしている場合の処理 } else { // コードのチェック仕様を満たしていない場合の処理 }
finalなのにadd?
finalで定数であることは宣言してるから…ってそれでいいのか?
腑に落ちなかったので、"final list java"でググって調べたところ、以下の記事を発見。
neos21.hatenablog.com
final List<String> NG_CODE_LIST = Collections.unmodifiableList(Arrays.asList("000", "999")); if(targetCode.matches("^[0-9a-zA-Z]{3}$") && !NG_CODE_LIST.contains(targetCode)) { // コードのチェック仕様を満たしている場合の処理 } else { // コードのチェック仕様を満たしていない場合の処理 }
この実装なら、NG_CODE_LISTにaddしようものなら例外が発生するようになる、ということらしい。
厳密に禁止したいときはこちらの方がよさげ。
あとついでに、Arrays.asListにしてみた。
可変(ArrayList)である必要ないし、問題ないよね?
https://docs.oracle.com/javase/jp/6/api/java/util/Arrays.html#asList(T...)
javaで正規表現
とあるコードが数字→英数字になる仕様変更に取り組んだときの、気づきと備忘録、その1。
チェック処理で正規表現を用いることになった。
javaで正規表現…
『SBクリエイティブ:体系的に学ぶ 安全なWebアプリケーションの作り方』を確認したところ、javaならmatchesメソッドが使える、とのこと。
matchesメソッド https://docs.oracle.com/javase/jp/6/api/java/lang/String.html#matches(java.lang.String)
"java 文字列 正規表現 チェック"でググって見つけた、以下の記事を参考にしながら、実装。
正規表現を使う - Javaちょこっとリファレンス
Javaで入力チェックを正規表現で行う - dirablueの日記
Javaで正規表現によるチェックについて - Java~PG CENTER(プログラムセンター)~
実装したものの、諸々の都合で、私はレビューにまわることに。
…で、上がってきた実装。
if(targetCode.matches("^[0-9a-zA-Z]{3}+$")) { // 正規表現を満たしている場合の処理 } else { // 正規表現を満たしていない場合の処理 }
"+"なくてもいいのでは?と指摘したものの、修正されず。
のちの試験で問題も出てないので、まあいいか、と流す。
Eclipseのブレークポイントに条件を追加する
Eclipseのデバッグを利用して、想定通りの判定処理になっているかどうか試験をしていた時のことです。
繰り返し処理中に何回も同じ値が出てくるため、次の該当値が出てくるまで何回もF8を押すのがダルくて、ラクできる方法を探そうと思い立ちました。
たまたま右クリックした時に出てきていた単語を絡めて、「Eclipse インスペクション」で検索したところ、下記のスライドを見つけました。
P.69の「Q22.ある条件を満たす時、初めて止まるようにブレークポイントを貼るにはどうすればよいですか?」がまさに自分のやりたいことでした。
Eclipseを日本語化している場合は、下記の操作になります。
1. ブレークポイントを右クリック
2. 「ブレークポイント・プロパティー」を選択
3. 「条件付き」チェックボックスを選択
※「'true'の時に中断」ラジオボタンが選択されていることを確認
4. テキストエリアに条件を入力
targetStr.equals("ヒット")
5. 「OK」を選択
この例だと、targetStrが"ヒット"の場合だけ、ブレークポイントで処理が止まるようになります。
目視確認はザルになりがちだし、ミスってまた最初からも嫌だし…この設定のおかげで、試験の時短になりました。
フィンランドの国語教育すごいなあ
■なぜ読んだのか
新人SE向けの記事を読み漁っている中で、たどり着いた記事で紹介されていた、フィンランドの議論のルールに興味を持ったから。
たどり着いた記事
Adways Engineers' Blog : 新人後輩SEに業務に入る前に読んで欲しい記事 15選
紹介されていた記事
また、上下関係で下である自分の意見に聞く耳を持ってもらえず、ストレスともどかしさを感じており、なにか解決の糸口が掴めるのでは?と思ったから。
▲自身のノートにはこのような嘆きが最近増えている
■読了にかかった期間・時間
1時間。届いた日に読了。
■備忘録
読了後、読んでよかったと思った。
練習してできるようになりたいことが、たくさん書かれていた。
実践してみたいことを書き出しておく。
□発想力のカルタ
それは何?
それで何をするの?
それはどんなもの?
中央のテーマは単語が実践しやすそう。
□表現力のカルタ
いつ?
どこで?
だれが?
何を?
なぜ?
どうやって?
それからどうなった?
こちらは中央は短文。創作などで使えそう。
□論理力
どうして?攻撃
池上彰氏の『伝える力』を思い出しました。日本銀行を社会の教科書を引用して説明すると、小さい子どもには伝わらず、素朴な疑問をぶつけられる、というお話。ここで「そういうものなんだよ」と言っちゃあ、おしまいだ…。
自分が疑問を持つことも大事だし、どうして?攻撃に筋の通った、納得のできる答えを返せるようになることも大事。
# 猫が好きなのはかわいいから→犬だってかわいいのにどうして猫?
意見+理由
意見
なぜなら(理由1)
それに(理由2)
また(理由3)
3つの理由がただの言い換えにならないように気をつけること。
理由を3つ述べて意見で殴れ。
□批判的思考力
いいところと悪いところを10個ずつ挙げる
悪いところだけを挙げるメソッドだったが、生徒が悪いところだけを挙げるのはいやだと言うのでいいところも挙げるようになったそうだ。見習いたい。
□コミュニケーション力
議論のルール。…は、すでにまとめてある記事も紹介したので、私が気になった点のみ、備忘録を残しておく。
1. 他人の発言をさえぎらない。
他人の発言中に勝手にしゃべりださない。例え発言中の人の意見がふざけていようが、途中でしゃべりだした人がルール違反。自分の発言の価値(と表現して伝わるのだろうか)を下げないためにも、大事なことかも。
6. 話を聞くときはほかのことをしない。
P.69のイラストでいうと、寝ている生徒がこのルールを違反しているということだろう。
8. 議論が台無しになるようなことを言わない。
【本書より引用】(前提に立ち返ると、他の人の気づかなかった論点を示したように見えるので、優越感に浸れるのです。)
突き刺さる一文。「そもそも」を禁止しようと思った。
10. 議論が終わったら、議論の内容の話はしない。
蒸し返して喧嘩になることがあり、ルール化されたそうだ。
本書を読んでいると、先生が生徒の提案でルールを改良しているようで、そういう受容性のある雰囲気も素晴らしいなあと思った。
『リーダブルコード』を読んで、備忘録
■なぜ読んだのか
試験要員化していた私に、コーディングの機会が巡ってくることになったから。
# 読みかけの本に飽きてきたから、という理由もある
■読了にかかった期間・時間
累計3時間くらい。
5/23-6/4の13日間のうち、7日着手。
■備忘録
本書における「リーダブルコード」「より良いコード」の定義は、「第三者が理解するまでにかかる時間が短いコード」であることを、まずはおさえておきたい。
そして、「第三者」には、未来の自分も含まれている。
とりあえず、これなら今の自分でも心がけ次第でできそうだと思ったことを抜き出しておく。
・【P.14】ループで使う変数に説明的な名前をつける
(例:i,j,k→ci,mi,ui)
・【P.20】変数に単位を含める
(例:start→start_ms)
・【P.21】変数に属性を含める
(例:html→html_utf8)
・【P.31】限界値の変数の接頭にmin_,max_をつける
・【P.32】以上以下の範囲を表す変数の接頭にfirst_,last_をつける
・【P.33】以上未満の範囲を表す変数の接頭にbegin_,end_をつける
・【P.77】名前付き引数っぽいコメントをつける
(例:checkRange(/* first_index = */ 1, /* last_index = */ 10))
・【P.84】条件式の左側には調査対象、右側には比較対象
(例:if(first_index >= 1))
・【P.91】関数から早く返す
# 関数の複数returnを許容しないのはアホくさいらしい。
# …が、ここは賛否が分かれそうな気がした
・【P.124】変数の変更箇所を少なくする
(現在値の判断が難しくなるのを避けるため)
・【P.127】標準のライブラリを利用する
(時間の節約になり、書くコードも少なくなる)
# 確かにこれは忘れがちだなと思った
・【P.229】1回のコミットにつき変更内容はひとつ
(例:1回目のコミット→コメント整形、2回目のコミット→今回の改修)
# コメント整形と今回の改修両方ぶち込んだらdiffとりにくいよな~と思って
# コメント整形しなかったことがあったんだけど
# こうすれば良かったんだ!と気づかせてもらった
過去のコメントがコードをただ日本語化しただけになってて、本書で書かれていた意味のないコメントだなって凹んだけど、これから気をつけたらいいよね!
なんちゃらMap
なんちゃらMap系のコードをいじるのでメモ。
■追加する場合
TreeMap:キーでソート
LinkedHashMap:追加された順
HashMap、TreeMap、LinkedHashMapの違いとLRU | infoScoop開発者ブログより
(ググったワード:"treemap linkedhashmap")
■ループ
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
for(Map.Entry<String,String> entry : map.entrySet()){
// entry.getKey()
// entry.getValue()
}
[java][基本] HashMap、HashSet、ArrayListのループ処理サンプル | keiのTECブログより
(ググったワード:"linkedhashmap ループ")
以下、6/27追記。
keyをIntegerからStringに変更したら、今までparseIntで同じkey扱いだった"01"と"1"が別keyとなっていた。
なんでかな…と調べたところ、重複したkeyで新たにputすると、valueは新しいものに置換される、とのこと。
(ググったワード:"treemap キー 重複")
APIの仕様にも書いてありました。
つまり、今までは新しいvalueで置換していたということか。
従来の処理と異なるので、確認事案でした。