My Photo

« SQLインジェクション その2 | Main | 鋼の錬金術師の最終巻を読み直した »

October 03, 2013

連続した日付、時間の文字列を作る秀丸マクロのサブルーチン

CSVファイルや大量のINSERT文などテストデータを作る際に連続した日付や時間を作りたかったので秀丸マクロのサブルーチンを3つ作ってみた。
いずれもformatNumという数値に前ゼロを付けて固定長の文字列を返すサブルーチンを使用している。

incrementDate1は年、月、日を渡してその+1日のYYYY/MM/DD形式の日付文字列を返す。年、月をまたぐことができる。閏年にも対応。
ただ、引数が3つあって使い方や下のincrementDate2よりやや面倒。

// 日付をインクリメント。月跨ぎ、年跨ぎ可。
// 引数1:年(整数)
// 引数2:月(整数)
// 引数3:日(整数)
// 戻り値:YYYY/MM/DD形式の文字列の日付
dateIncrement1:
	##iYear  = ##1;
	##iMonth = ##2;
	##iDay   = ##3;
	
	##iDay = ##iDay + 1;
	
	// 31日ある月
	if (##iMonth == 1 || ##iMonth == 3 || ##iMonth == 5
	    || ##iMonth == 7 || ##iMonth == 8 || ##iMonth == 10
	    || ##iMonth == 12) {
		if (##iDay == 32) {
			##iDay = 1;
			if (##iMonth == 12) {
				##iYear = ##iYear + 1;
				##iMonth = 1;
			} else {
				##iMonth = ##iMonth + 1;
			}
		}
		
	// 30日ある月
	} else if (##iMonth == 2) {
		if (##iDay == 31) {
			##iDay = 1;
			##iMonth = ##iMonth + 1;
		}
	
	// 2月
	} else {
		if (##iYear % 4 == 0) {
			if (##iDay == 30) {
				##iDay = 1;
				##iMonth = ##iMonth + 1;
			}
		} else {
			if (##iDay == 29) {
				##iDay = 1;
				##iMonth = ##iMonth + 1;
			}
		}
	}
	
	call formatNum ##iMonth, 2;
	$$strMonth = $$return;
	call formatNum ##iDay, 2;
	$$strDay = $$return;
	
	$$strDate = str(##iYear) + "/" + $$strMonth + "/" + $$strDay;
	return $$strDate;

incrementDate2は年の日数(1月1日なら1)を渡し、その日のMM/DD形式の日付文字列を返す。年はまたげない。月またぎは可能。
引数は1つで使い方は簡単。

// 日付をインクリメント。月跨ぎ可。
// 引数1:年の日数(整数)。
//         1ならば戻り値は"01/01"、32ならば"02/01"となる。
// 戻り値:MM/DD形式の文字列の日付
dateIncrement2:
	##iDayNum   = ##1;
	
	##uruuBi = 0;	// うるう年の場合、1
	
	if (##iDayNum >= 31) {
		$$strMonth = "01";
		##iDay = ##iDayNum % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (59 + ##uruuBi)) {
		$$strMonth = "02";
		##iDay = (##iDayNum - 31) % (28+ ##uruuBi);
		if (##iDay == 0) { ##iDay = (28+ ##uruuBi); }
	} else if (##iDayNum >= (90 + ##uruuBi)) {
		$$strMonth = "03";
		##iDay = (##iDayNum - (59 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (120 + ##uruuBi)) {
		$$strMonth = "04";
		##iDay = (##iDayNum - (90 + ##uruuBi)) % 30;
		if (##iDay == 0) { ##iDay = 30; }
	} else if (##iDayNum >= (151 + ##uruuBi)) {
		$$strMonth = "05";
		##iDay = (##iDayNum - (120 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (181 + ##uruuBi)) {
		$$strMonth = "06";
		##iDay = (##iDayNum - (151 + ##uruuBi)) % 30;
		if (##iDay == 0) { ##iDay = 30; }
	} else if (##iDayNum >= (212 + ##uruuBi)) {
		$$strMonth = "07";
		##iDay = (##iDayNum - (181 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (243 + ##uruuBi)) {
		$$strMonth = "08";
		##iDay = (##iDayNum - (212 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (273 + ##uruuBi)) {
		$$strMonth = "09";
		##iDay = (##iDayNum - (243 + ##uruuBi)) % 30;
		if (##iDay == 0) { ##iDay = 30; }
	} else if (##iDayNum >= (304 + ##uruuBi)) {
		$$strMonth = "10";
		##iDay = (##iDayNum - (273 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else if (##iDayNum >= (334 + ##uruuBi)) {
		$$strMonth = "11";
		##iDay = (##iDayNum - (304 + ##uruuBi)) % 30;
		if (##iDay == 0) { ##iDay = 30; }
	} else if (##iDayNum >= (365 + ##uruuBi)) {
		$$strMonth = "12";
		##iDay = (##iDayNum - (334 + ##uruuBi)) % 31;
		if (##iDay == 0) { ##iDay = 31; }
	} else {	// エラー
		$$strMonth = "99";
		##iDay = 99;
	}
	
	call formatNum ##iDay, 2;
	$$strDay = $$return;
	
	$$strDate = $$strMonth + "/" + $$strDay;
	return $$strDate;

incrementTimeは0時0分を0として日の分数を渡しHH:MM形式の時間の文字列を返す。

// 分をインクリメント
// 引数1:0時0分からの経過時間。分(整数)。
//         0なら戻り値は"00:00"、90ならば"01:30"となる。
// 戻り値:HH:MM形式の時間の文字列
timeIncrement:
	##i  = ##1;
	
	##i = ##i % (60 * 24);
	##iHour = ##i / 60;
	##iMin  = ##i % 60;
	
	call formatNum ##iHour, 2;
	$$strHour = $$return;
	
	call formatNum ##iMin, 2;
	$$strMin = $$return;
	
	$$strTime = $$strHour + ":" + $$strMin;
	return $$strTime;

以下はこれらのサブルーチンを使ってINSERT分をたくさん作るマクロ。

// 日付、時間をインクリメント
disabledraw;
#start = 1;	// 初期値
#end =   15;	// 終了値

// dateIncrement1用パラメータ
#year  = 2013;
#month = 12;
#day   = 25;

// dateIncrement2用パラメータ
#day2 = 55;

// timeIncrement用パラメータ
#min = 290;

#i = #start;
while (#i <= #end) {
	call formatNum #i, 2;
	$num = $$return;

	call dateIncrement1 #year, #month, #day;
	$strDate = $$return;

	call dateIncrement2 #day2;
	$strDate2 = $$return;

	call timeIncrement #min;
	$strTime = $$return;

	insert "INSERT INTO table1 (id, date1, date2, time1, amount) VALUES ";
	insert "(10" + $num + ", '" + $strDate + "', '"
           + $strDate2 + "', '" + $strTime + "', " + str(#i) + ");\n";

	#i = #i + 1;
	
	#day2 = #day2 + 1;	// +1日
	
	#min = #min + 5;	// +5分
	
	#year  = val(midstr($strDate, 0, 4));	// 年を整数で抽出
	#month = val(midstr($strDate, 5, 2));	// 月を整数で抽出
	#day   = val(midstr($strDate, 8, 2));	// 日を整数で抽出
}
enabledraw;
endmacro;


// 数値に前ゼロを付けて指定した桁数の文字列を作成する。
// 引数1:素になる数値
// 引数2:桁数
// 戻り値:引数1に必要ならば前ゼロを付けて引数2の桁数にした文字列。
formatNum:
	##num1 = ##1;
	$$str1 = str(##num1);
	##keta = ##2;
	##len1 = strlen($$str1);
	while (##len1 < ##keta) {
		$$str1 = "0" + $$str1;
		##len1 = ##len1 + 1;
	}
	return $$str1;


// 日付をインクリメント。月跨ぎ、年跨ぎ可。
// 引数1:年(整数)
// 引数2:月(整数)
// 引数3:日(整数)
// 戻り値:YYYY/MM/DD形式の文字列の日付
dateIncrement1:
// 省略

// 日付をインクリメント。月跨ぎ可。
// 引数1:年の日数(整数)。
//         1ならば戻り値は"01/01"、32ならば"02/01"となる。
// 戻り値:MM/DD形式の文字列の日付
dateIncrement2:
// 省略

// 分をインクリメント
// 引数1:0時0分からの経過時間。分(整数)。
//         0なら戻り値は"00:00"、90ならば"01:30"となる。
// 戻り値:HH:MM形式の時間の文字列
timeIncrement:
// 省略

出力は以下のようになる。

INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1001, '2013/12/26', '02/24', '04:50', 1);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1002, '2013/12/27', '02/25', '04:55', 2);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1003, '2013/12/28', '02/26', '05:00', 3);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1004, '2013/12/29', '02/27', '05:05', 4);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1005, '2013/12/30', '02/28', '05:10', 5);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1006, '2013/12/31', '03/01', '05:15', 6);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1007, '2014/01/01', '03/02', '05:20', 7);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1008, '2014/01/02', '03/03', '05:25', 8);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1009, '2014/01/03', '03/04', '05:30', 9);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1010, '2014/01/04', '03/05', '05:35', 10);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1011, '2014/01/05', '03/06', '05:40', 11);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1012, '2014/01/06', '03/07', '05:45', 12);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1013, '2014/01/07', '03/08', '05:50', 13);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1014, '2014/01/08', '03/09', '05:55', 14);
INSERT INTO table1 (id, date1, date2, time1, amount) VALUES (1015, '2014/01/09', '03/10', '06:00', 15);

« SQLインジェクション その2 | Main | 鋼の錬金術師の最終巻を読み直した »

秀丸エディタ」カテゴリの記事

Comments

Post a comment

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/26461/58315472

Listed below are links to weblogs that reference 連続した日付、時間の文字列を作る秀丸マクロのサブルーチン:

« SQLインジェクション その2 | Main | 鋼の錬金術師の最終巻を読み直した »

September 2017
Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof