本ページには広告が含まれています。
引数に指定した年、月、日の日付が表すシリアル値を返します。
- 構文
- serial = dateSerial( year, month, day )
- 引数
- year 必須
- 年
- month 必須
- 月
- day 必須
- 日
- 戻り値
- シリアル値
プログラム
////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // 【戻り値】 // シリアル値 ////////////////////////////////////////////////// FUNCTION dateSerial(year, month, day) month = REPLACE(FORMAT(month, 2), " ", "0") day = REPLACE(FORMAT(day, 2), " ", "0") d = GETTIME(0, year + "/" + month + "/" + day) RESULT = uwscToSerial(d) FEND ////////////////////////////////////////////////// // 【引数】 // uwscTime : UWSC時間 // 【戻り値】 // シリアル値 ////////////////////////////////////////////////// FUNCTION uwscToSerial(uwscTime) uwscDate = uwscTime / 86400 RESULT = 36526 + uwscDate FEND
シリアル値
シリアル値とは1900年1月1日を1とし、その日からの通算日数と時刻を表す値のことです。1日毎に1ずつ増え、小数部分が時刻を表します。
日付
時刻
シリアル値で時刻は小数部分で表されます。
1日で1増えるので、1時間は1/24で0.41666666…、1分は1/1440で0.00069444444…、1秒は1/86400で0.0000115740740…増えることになります。
時刻hh:nn:ssのシリアル値は以下の式で求めることができます。
24時間=86400秒。時分秒を秒単位に直して86400で割る。
1時間=3600秒、1分=60秒。
hh×3600+nn×60+ss86400プログラム実行例
コロナのグラフ
CONST xlDown = -4121 CONST xlColumnClustered = 51 CONST xlCategory = 1 CONST xlValue = 2 CONST xlLine = 4 CONST msoThemeColorText2 = 15 CONST msoThemeColorBackground1 = 14 DIM Excel = CREATEOLEOBJ("Excel.Application") WITH Excel .Visible = TRUE .Workbooks.Open("D:\Downloads\covid19_data.csv") DIM ws = .ActiveSheet DIM ws2 = .Worksheets.Add(EMPTYPARAM, .Worksheets(.Worksheets.Count)) ws2.Name = "7日間平均" ws.Range("1:1").Copy(ws2.Range("1:1")) ws.Range("A:D").Copy(ws2.Range("A:D")) ws.Range("W:AB").Copy(ws2.Range("W:AB")) ws2.Range("E8").Value = "=INT(SUM(covid19_data!E2:E8)/7)" ws2.Range("E8").AutoFill(ws2.Range("E8:V8")) DIM lastRow = ws.Range("B2").End(xlDown).Row ws2.Range("E8:V8").AutoFill(ws2.Range("E8:V" + lastRow)) DIM Chart // 検査数 Chart = .Charts.Add .ActiveSheet.Move(EMPTYPARAM, .Sheets(.Sheets.Count)) .ActiveSheet.Name = "検査数" WITH Chart .ChartType = xlColumnClustered .SetSourceData(ws.Range("covid19_data!$E:$E")) WITH .SeriesCollection(1) .Name = "日検査数" .XValues = "covid19_data!$Y2:$Y" + lastRow WITH .Format.Line .ForeColor.ObjectThemeColor = msoThemeColorText2 .ForeColor.TintAndShade = 0 .ForeColor.Brightness = 0.6000000238 .Transparency = 0 ENDWITH ENDWITH WITH .Axes(xlCategory) .MinimumScale = dateSerial(2020, 1, 1) //43831 .MajorUnit = 4 .TickLabels.Font.Size = 14 ENDWITH WITH .Axes(xlValue) .HasMajorGridLines = TRUE .HasMinorGridLines = TRUE .MinimumScale = 0 .MajorUnit = 5000 .MinorUnit = 1000 .TickLabels.Font.Size = 14 ENDWITH ENDWITH // 陽性数 Chart = .Charts.Add .ActiveSheet.Move(EMPTYPARAM, .Sheets(.Sheets.Count)) .ActiveSheet.Name = "陽性者数" WITH Chart .ChartType = xlColumnClustered .SetSourceData(ws.Range("covid19_data!$G2:$G" + lastRow)) .SeriesCollection.NewSeries .SeriesCollection(2).Values = "='7日間平均'!$G2:$G" + lastRow // 日付 WITH .SeriesCollection(1) .Name = "日陽性数" .XValues = "covid19_data!$Y2:$Y" + lastRow WITH .Format.Line .ForeColor.ObjectThemeColor = msoThemeColorText2 .ForeColor.TintAndShade = 0 .ForeColor.Brightness = 0.6000000238 .Transparency = 0 ENDWITH ENDWITH // 7日間平均 WITH .SeriesCollection(2) .Name = "7日間平均" .ChartType = xlLine .Format.Line.ForeColor.RGB = RGBToColor(0, 112, 192) ENDWITH // x軸 WITH .Axes(xlCategory) .MinimumScale = dateSerial(2020, 1, 1) //43831 .MajorUnit = 4 .TickLabels.Font.Size = 14 ENDWITH // y軸 WITH .Axes(xlValue) .HasMajorGridLines = TRUE .HasMinorGridLines = TRUE .MinimumScale = 0 .MajorUnit = 5000 .MinorUnit = 1000 .TickLabels.Font.Size = 14 ENDWITH ENDWITH // 死亡数 Chart = .Charts.Add .ActiveSheet.Move(EMPTYPARAM, .Sheets(.Sheets.Count)) .ActiveSheet.Name = "死亡数" WITH Chart .ChartType = xlColumnClustered .SetSourceData(ws.Range("covid19_data!$O2:$O" + lastRow)) .SeriesCollection.NewSeries .SeriesCollection(2).Values = "='7日間平均'!$O2:$O" + lastRow WITH .SeriesCollection(1) .Name = "日死亡数" .XValues = "covid19_data!$Y2:$Y" + lastRow WITH .Format.Line .ForeColor.ObjectThemeColor = msoThemeColorBackground1 .ForeColor.TintAndShade = 0 .ForeColor.Brightness = -0.150000006 .Transparency = 0 ENDWITH ENDWITH WITH .SeriesCollection(2) .Name = "7日間平均" .ChartType = xlLine WITH .Format.Line .Weight = 2.5 .Transparency = 0 .ForeColor.ObjectThemeColor = msoThemeColorBackground1 .ForeColor.TintAndShade = 0 .ForeColor.Brightness = -0.5 ENDWITH ENDWITH WITH .Axes(xlCategory) .MinimumScale = dateSerial(2020, 1, 1) //43831 .MajorUnit = 4 .TickLabels.Font.Size = 14 ENDWITH WITH .Axes(xlValue) .HasMajorGridLines = TRUE // 軸あり .HasMinorGridLines = TRUE // 目盛線あり .MinimumScale = 0 // 最小値 .TickLabels.Font.Size = 14 // フォントサイズ ENDWITH ENDWITH // 死亡累計 Chart = .Charts.Add .ActiveSheet.Move(EMPTYPARAM, .Sheets(.Sheets.Count)) .ActiveSheet.Name = "死亡累計" WITH Chart .ChartType = xlColumnClustered .SetSourceData(ws.Range("covid19_data!$P2:$P" + lastRow)) WITH .SeriesCollection(1) .Name = "死亡累計" .XValues = "covid19_data!$Y2:$Y" + lastRow WITH .Format.Line .ForeColor.ObjectThemeColor = msoThemeColorBackground1 .ForeColor.TintAndShade = 0 .ForeColor.Brightness = -0.150000006 .Transparency = 0 ENDWITH ENDWITH WITH .Axes(xlCategory) .MinimumScale = dateSerial(2020, 1, 1) //43831 .MajorUnit = 4 .TickLabels.Font.Size = 14 ENDWITH WITH .Axes(xlValue) .HasMajorGridLines = TRUE // 軸あり .MinimumScale = 0 // 最小値 .TickLabels.Font.Size = 14 // フォントサイズ ENDWITH .ChartTitle.Delete ENDWITH ENDWITH ////////////////////////////////////////////////// // 【引数】 // bin : 2進数 // signFlg : 符号付きならばTrue // 【戻り値】 // 10進数に変換した値 ////////////////////////////////////////////////// FUNCTION binToDec(bin, signFlg = TRUE) DIM dec = 0 DIM decimalFlg = IIF(POS(".", bin), TRUE, FALSE) IFB COPY(bin, 1, 1) = "1" AND signFlg THEN DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin)) DIM lsb = IIF(decimalFlg, POS(".", bin) - LENGTH(bin), 0) DIM dec2 = POWER(2, msb) - 1 FOR i = -1 TO lsb STEP -1 dec2 = dec2 + POWER(2, i) NEXT DIM a = binToDec(bin, FALSE) DIM b = dec2 dec = -1 * (bitXor(a, b) + POWER(2, lsb)) ELSE IFB decimalFlg THEN DIM integer = COPY(bin, 1, POS(".", bin) - 1) DIM decimal = COPY(bin, POS(".", bin) + 1) FOR i = 1 TO LENGTH(decimal) dec = dec + COPY(decimal, i, 1) * POWER(2, -1 * i) NEXT ELSE integer = bin ENDIF FOR i = 1 TO LENGTH(integer) dec = dec + COPY(integer, i, 1) * POWER(2, LENGTH(integer) - i) NEXT ENDIF RESULT = dec FEND ////////////////////////////////////////////////// // 【引数】 // bin : 2進数 // 【戻り値】 // 16進数に変換した値 ////////////////////////////////////////////////// FUNCTION binToHex(bin) HASHTBL bh bh["0000"] = "0"; bh["0001"] = "1"; bh["0010"] = "2"; bh["0011"] = "3"; bh["0100"] = "4"; bh["0101"] = "5"; bh["0110"] = "6"; bh["0111"] = "7"; bh["1000"] = "8"; bh["1001"] = "9"; bh["1010"] = "A"; bh["1011"] = "B"; bh["1100"] = "C"; bh["1101"] = "D"; bh["1110"] = "E"; bh["1111"] = "F"; // 小数ならば IFB POS(".", bin) <> 0 THEN DIM num = COPY(bin, 1, POS(".", bin) - 1) DIM frac = COPY(bin, POS(".", bin) + 1) num = strPad(num, CEIL(LENGTH(num) / 4) * 4, "0", LEFT) frac = strPad(frac, CEIL(LENGTH(frac) / 4) * 4, "0", RIGHT) DIM hex = "" FOR i = 1 TO LENGTH(num) STEP 4 hex = hex + bh[COPY(num, i, 4)] NEXT hex = hex + "." FOR i = 1 TO LENGTH(frac) STEP 4 hex = hex + bh[COPY(frac, i, 4)] NEXT RESULT = hex ELSE len = CEIL(LENGTH(bin) / 4) * 4 FOR i = 1 TO len - LENGTH(bin) bin = "0" + bin NEXT bin = REPLACE(FORMAT(bin, len), " ", "0") hex = "" FOR i = 1 TO LENGTH(bin) / 4 str = COPY(bin, i * 4 - 3, 4) hex = hex + bh[str] NEXT RESULT = hex ENDIF FEND ////////////////////////////////////////////////// // 【引数】 // num : 10進数もしくは2進数の値 // bit : ビット // 【戻り値】 // ビットを反転した値 ////////////////////////////////////////////////// FUNCTION bitNot(num, bit = EMPTY) IFB isString(num) THEN DIM res = "" FOR i = 1 TO LENGTH(num) DIM str = COPY(num, i, 1) IFB str = "0" OR str = "1" THEN res = res + (1 - VAL(str)) ELSE res = res + str ENDIF NEXT RESULT = res ELSE DIM exponent = IIF(bit = EMPTY, CEIL(LOGN(2, num + 1)), bit) RESULT = POWER(2, exponent) - num - 1 ENDIF FEND ////////////////////////////////////////////////// // 【引数】 // arg1 : 数値1(10進数) // arg2 : 数値2(10進数) // 【戻り値】 // 2つの数値のビット毎の排他的論理和 ////////////////////////////////////////////////// FUNCTION bitXor(arg1, arg2) DIM args[1] = arg1, arg2 DIM bins[1] DIM decimals[1] DIM integers[1] DIM keta[1] IFB ABS(arg1) <> arg1 OR ABS(arg2) <> arg2 THEN RESULT = ERR_VALUE EXIT ENDIF FOR i = 0 TO 1 bins[i] = decToBin(args[i]) decimals[i] = 0 IFB POS(".", bins[i]) <> 0 THEN integers[i] = COPY(bins[i], 1, POS(".", bins[i]) - 1) decimals[i] = COPY(bins[i], POS(".", bins[i]) + 1) ELSE integers[i] = bins[i] ENDIF NEXT keta[0] = IIF(LENGTH(integers[0]) > LENGTH(integers[1]), LENGTH(integers[0]), LENGTH(integers[1])) integers[0] = strPad(integers[0], keta[0], "0", LEFT) integers[1] = strPad(integers[1], keta[0], "0", LEFT) keta[1] = IIF(LENGTH(decimals[0]) > LENGTH(decimals[1]), LENGTH(decimals[0]), LENGTH(decimals[1])) decimals[0] = strPad(decimals[0], keta[1], "0", RIGHT) decimals[1] = strPad(decimals[1], keta[1], "0", RIGHT) DIM bin = "" FOR i = 1 TO keta[0] bin = bin + (VAL(COPY(integers[0], i, 1)) XOR VAL(COPY(integers[1], i, 1))) NEXT bin = bin + "." FOR i = 1 TO keta[1] bin = bin + (VAL(COPY(decimals[0], i, 1)) XOR VAL(COPY(decimals[1], i, 1))) NEXT RESULT = binToDec(bin) FEND ////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // 【戻り値】 // シリアル値 ////////////////////////////////////////////////// FUNCTION dateSerial(year, month, day) month = REPLACE(FORMAT(month, 2), " ", "0") day = REPLACE(FORMAT(day, 2), " ", "0") d = GETTIME(0, year + "/" + month + "/" + day) RESULT = uwscToSerial(d) FEND ////////////////////////////////////////////////// // 【引数】 // dec : 10進数 // signFlg : 符号付きならばTrueを指定 // digits : 変換した2進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定 // errorMsg : エラーメッセージを出力するかを示すブール値 // 【戻り値】 // 2進数に変換した値 ////////////////////////////////////////////////// FUNCTION decToBin(dec, signFlg = FALSE, digits = FALSE, errorMsg = FALSE) // 負数で符号なしならばエラー値を返す IFB dec < 0 AND signFlg = FALSE THEN PRINT "負数の場合signFlgにTrueを指定してください" RESULT = ERR_VALUE EXIT ENDIF // digitsのビット数が足りなければエラー値を返す、負数なら1桁多く取る IFB VARTYPE(digits) <> VAR_BOOLEAN AND digits < CEIL(LOGN(2, ABS(dec))) + IIF(dec < 0, 1, 0) THEN PRINT "ビット数が足りません" RESULT = ERR_VALUE EXIT ENDIF // signFlgがTrueかつdigitsがFalseならばエラー値を返す IFB signFlg AND !digits THEN PRINT "signFlgがTrueのときdigitsはFalse以外を選択してください" RESULT = ERR_VALUE EXIT ENDIF // bin:2進数に変換した結果を代入する変数 DIM bin = "" DIM msg = "" DIM isError = FALSE DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE) DIM negativeFlg = IIF(dec < 0, TRUE, FALSE) dec = ABS(dec) // (1) 10進数を整数部と小数部に分ける DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec) DIM decimal = IIF(decimalFlg, "0." + COPY(dec, POS(".", dec) + 1), 0) // (2) 10進数(整数部)を2進数に変換する。 REPEAT bin = (integer MOD 2) + bin integer = INT(integer / 2) UNTIL integer = 0 // (3) 10進数(小数部)を2進数に変換する。 IFB decimalFlg THEN bin = bin + "." DIM loop = 0 REPEAT loop = loop + 1 decimal = decimal * 2 bin = bin + IIF(decimal >= 1, "1", "0") IF decimal > 1 THEN decimal = decimal - 1 UNTIL decimal = 1 OR loop > 64 ENDIF // digitsがFALSE以外なら IFB digits THEN // (4) 2進数の桁合わせを行う DIM tmp = bin DIM binInteger = TOKEN(".", tmp) DIM binDecimal = TOKEN(".", tmp) // 整数部、小数部を4bit単位になるまで拡張 // 整数部、4の倍数になるまで整数部の先頭に'0'を追加 IF LENGTH(binInteger) MOD 4 <> 0 THEN binInteger = strRepeat("0", 4 - LENGTH(binInteger) MOD 4) + binInteger // 小数部、4の倍数になるまで小数部の末尾に'0'を追加 IF LENGTH(binDecimal) MOD 4 <> 0 THEN binDecimal = binDecimal + strRepeat("0", 4 - LENGTH(binDecimal) MOD 4) DIM digit = LENGTH(binInteger + binDecimal) // 10進数の場合、一旦自動調整を行う integer = INT(dec) IF signFlg AND COPY(binInteger, 1, 1) = "1" THEN binInteger = strRepeat("0", 4) + binInteger IFB signFlg THEN IFB integer >= -128 AND integer <= 127 THEN // -2^7〜2^7-1 binInteger = strRepeat("0", 8 - LENGTH(binInteger)) + binInteger ELSEIF integer >= -32768 AND integer <= 32767 THEN // -2^15〜2^15-1 binInteger = strRepeat("0", 16 - LENGTH(binInteger)) + binInteger ELSEIF integer >= -8388608 AND integer <= 8388607 THEN // -2^23〜2^23-1 binInteger = strRepeat("0", 24 - LENGTH(binInteger)) + binInteger ELSEIF integer >= -2147783648 AND integer <= 2147483647 THEN // -2^31〜2^31-1 binInteger = strRepeat("0", 32 - LENGTH(binInteger)) + binInteger ELSE binInteger = strRepeat("0", 64 - LENGTH(binInteger)) + binInteger ENDIF ELSE IFB integer <= 255 THEN // 2^8-1 binInteger = strRepeat("0", 8 - LENGTH(binInteger)) + binInteger ELSEIF integer <= 65535 THEN // 2^16-1 binInteger = strRepeat("0", 16 - LENGTH(binInteger)) + binInteger ELSEIF integer <= 16777215 THEN // 2^24-1 binInteger = strRepeat("0", 24 - LENGTH(binInteger)) + binInteger ELSEIF integer <= 4294967295 THEN // 2^32-1 binInteger = strRepeat("0", 32 - LENGTH(binInteger)) + binInteger ELSE binInteger = strRepeat("0", 64 - LENGTH(binInteger)) + binInteger ENDIF ENDIF totalDigits = LENGTH(binInteger + binDecimal) IFB totalDigits > 64 THEN DIM del32 = totalDigits - 32 DIM del64 = totalDigits - 64 IFB del32 = LENGTH(binDecimal) AND digits <> 64 THEN binDecimal = "" msg = "32bitを超えたため、小数点以下を削除しました" ELSEIF del32 < LENGTH(binDecimal) AND digits <> 64 THEN binDecimal = COPY(binDecimal, 1, LENGTH(binDecimal) - del32) msg = "32bitを超えたため、小数点以下の一部を削除しました" ELSEIF del64 = LENGTH(binDecimal) AND del64 <> 0 THEN binDecimal = "" msg = "64bitを超えたため、小数点以下を削除しました" ELSEIF del64 < LENGTH(binDecimal) THEN binDecimal = COPY(binDecimal, 1, LENGTH(binDecimal) - del64) msg = "64bitを超えたため、小数点以下の一部を削除しました" ELSE msg = "64bitを超えるため、変換できません" isError = TRUE ENDIF ENDIF // 整数部、小数部の合計桁数を8,16,24,32,64bit単位になるまで拡張 digit = LENGTH(binInteger + binDecimal) DIM array[] = 8, 16, 24, 32, 64 FOR item IN array IFB digit <= item THEN binInteger = strRepeat("0", item - digit) + binInteger BREAK ENDIF NEXT // 指定ビットに調整 // 合計桁数の再設定 totalDigits = LENGTH(binInteger + binDecimal) IFB digits = TRUE THEN // 桁合わせを自動調整 IFB totalDigits > 64 THEN len = LENGTH(binInteger + binDecimal) WHILE LENGTH(binInteger) > 8 AND len > digits IFB COPY(binInteger, 1, 4) = "0000" THEN binInteger = COPY(binInteger, 5) len = len - 4 ELSE BREAK ENDIF WEND WHILE LENGTH(binDecimal) > 4 AND LENGTH(binInteger + binDecimal) > digits IFB COPY(binDecimal, LENGTH(binDecimal) - 4) = "0000" THEN binDecimal = COPY(binDecimal, 1, LENGTH(binDecimal) - 4) ELSE BREAK ENDIF WEND tmp = binInteger + "." + binDecimal binInteger = COPY(tmp, 1, POS(".", tmp) - 1) binDecimal = COPY(tmp, POS(".", tmp) + 1) totalDigits = LENGTH(binInteger + binDecimal) IFB totalDigits > 64 THEN isError = TRUE msg = "64bitを超えたため変換できません" ENDIF ENDIF ELSE // 指定ビットに調整 IFB totalDigits <= digits THEN binInteger = strPad(binInteger, digits - LENGTH(binDecimal), "0", LEFT) ELSE // 桁あふれ調整 totalDigits = LENGTH(binInteger + binDecimal) len = LENGTH(binInteger + binDecimal) WHILE LENGTH(binInteger) > 8 AND len > digits IFB COPY(binInteger, 1, 4) = "0000" THEN binInteger = COPY(binInteger, 5) len = len - 4 ELSE BREAK ENDIF WEND WHILE LENGTH(binDecimal) > 4 AND LENGTH(binInteger + binDecimal) > digits IFB COPY(binDecimal, LENGTH(binDecimal) - 4) = "0000" THEN binDecimal = COPY(binDecimal, 1, LENGTH(binDecimal) - 4) ELSE BREAK ENDIF WEND tmp = binInteger + "." + binDecimal binInteger = COPY(tmp, 1, POS(".", tmp) - 1) binDecimal = COPY(tmp, POS(".", tmp) + 1) len = LENGTH(binInteger + binDecimal) IFB len > digits THEN DIM deleteLength = len - digits IFB deleteLength = LENGTH(binDecimal) THEN binDecimal = "" msg = "指定ビット数にするため小数点以下を削除しました" ELSEIF deleteLength < LENGTH(binDecimal) THEN binDecimal = COPY(binDecimal, 1, LENGTH(binDecimal) - deleteLength) msg = "指定ビット数にするため小数点以下の一部を削除しました" ELSE isError = TRUE msg = "指定ビット数では変換できません" ENDIF ENDIF ENDIF ENDIF bin = binInteger + IIF(binDecimal <> "", "." + binDecimal, "") // (5) 入力値がマイナスのため、2進数をマイナス値に変換する IFB negativeFlg THEN // 1の補数 bin = bitNot(bin) // 2の補数 DIM res = "" DIM carry = "1" FOR i = LENGTH(bin) TO 1 STEP -1 IFB carry = "1" THEN SELECT COPY(bin, i, 1) CASE "0" res = "1" + res carry = 0 CASE "1" res = "0" + res DEFAULT res = COPY(bin, i, 1) + res SELEND ELSE res = COPY(bin, i, 1) + res ENDIF NEXT bin = res ENDIF ENDIF IF errorMsg AND msg <> "" THEN PRINT msg RESULT = IIF(isError, ERR_VALUE, bin) FEND ////////////////////////////////////////////////// // 【引数】 // dec : 10進数 // signFlg : 符号付きならばTrue // digits : 変換した16進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定 // errorMsg : エラーメッセージを出力するかを示すブール値 // 【戻り値】 // 16進数に変換した値 ////////////////////////////////////////////////// FUNCTION decToHex(dec, signFlg = FALSE, digits = FALSE, errorMsg = FALSE) DIM hex = "" DIM msg = "" DIM isError = FALSE DIM dec2hex[] = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE) DIM negativeFlg = IIF(dec < 0, TRUE, FALSE) dec = ABS(dec) // (1) 10進数を整数部と小数部に分ける DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec) DIM decimal = IIF(decimalFlg, "0." + COPY(dec, POS(".", dec) + 1), 0) // (2) 10進数(整数部)を16進数に変換する。 REPEAT hex = dec2hex[integer MOD 16] + hex integer = INT(integer / 16) UNTIL integer = 0 // (3) 10進数(小数部)を16進数に変換する。 IFB decimalFlg THEN hex = hex + "." DIM loop = 0 REPEAT loop = loop + 1 decimal = decimal * 16 hex = hex + dec2hex[decimal] offset = POWER(10, LENGTH(decimal) - POS(".", decimal)) decimal = (decimal * offset - INT(decimal) * offset) / offset UNTIL decimal = 0 OR loop > 16 ENDIF // digitsがFALSE以外なら IFB digits THEN // (4) 16進数の桁合わせを行う DIM tmp = hex DIM hexInteger = TOKEN(".", tmp) DIM hexDecimal = TOKEN(".", tmp) // 整数部、小数部を4bit単位になるまで拡張 // 整数部、4の倍数になるまで整数部の先頭に'0'を追加 // ※16進数は4bit単位なのでこの処理は不要 DIM digit = LENGTH(hexInteger + hexDecimal) integer = INT(dec) IF signFlg AND COPY(hexToBin(hexInteger), 1, 1) = "1" THEN hexInteger = "0" + hexInteger IFB signFlg THEN IFB integer >= -128 AND integer <= 127 THEN // -2^7〜2^7-1 hexInteger = strRepeat("0", 2 - LENGTH(hexInteger)) + hexInteger ELSEIF integer >= -32768 AND integer <= 32767 THEN // -2^15〜2^15-1 hexInteger = strRepeat("0", 4 - LENGTH(hexInteger)) + hexInteger ELSEIF integer >= -8388608 AND integer <= 8388607 THEN // -2^23〜2^23-1 hexInteger = strRepeat("0", 6 - LENGTH(hexInteger)) + hexInteger ELSEIF integer >= -2147783648 AND integer <= 2147483647 THEN // -2^31〜2^31-1 hexInteger = strRepeat("0", 8 - LENGTH(hexInteger)) + hexInteger ELSE hexInteger = strRepeat("0", 16 - LENGTH(hexInteger)) + hexInteger ENDIF ELSE IFB integer <= 255 THEN // 2^8-1 hexInteger = strRepeat("0", 2 - LENGTH(hexInteger)) + hexInteger ELSEIF integer <= 65535 THEN // 2^16-1 hexInteger = strRepeat("0", 4 - LENGTH(hexInteger)) + hexInteger ELSEIF integer <= 16777215 THEN // 2^24-1 hexInteger = strRepeat("0", 6 - LENGTH(hexInteger)) + hexInteger ELSEIF integer <= 4294967295 THEN // 2^32-1 hexInteger = strRepeat("0", 8 - LENGTH(hexInteger)) + hexInteger ELSE hexInteger = strRepeat("0", 16 - LENGTH(hexInteger)) + hexInteger ENDIF ENDIF totalDigits = LENGTH(hexInteger + hexDecimal) * 4 // 64bitを超えたら IFB totalDigits > 64 THEN DIM del32 = totalDigits - 32 DIM del64 = totalDigits - 64 IFB del32 = LENGTH(hexDecimal) * 4 AND digits <> 64 THEN hexDecimal = "" msg = "32bitを超えたため、小数点以下を削除しました" ELSEIF del32 < LENGTH(hexDecimal) * 4 AND digits <> 64 THEN hexDecimal = COPY(hexDecimal, 1, (LENGTH(hexDecimal) * 4 - del32) / 4) msg = "32bitを超えたため、小数点以下の一部を削除しました" ELSEIF del64 = LENGTH(hexDecimal) * 4 AND del64 <> 0 THEN hexDecimal = "" msg = "64bitを超えたため、小数点以下を削除しました" ELSEIF del64 < LENGTH(hexDecimal) * 4 THEN hexDecimal = COPY(hexDecimal, 1, (LENGTH(hexDecimal) * 4 - del64) / 4) msg = "64bitを超えたため、小数点以下の一部を削除しました" ELSE isError = TRUE msg = "64bitを超えるため、変換できません" ENDIF ENDIF // 整数部、小数部の合計桁数を8,16,24,32,64bit単位になるまで拡張 digit = LENGTH(hexInteger + hexDecimal) DIM array[] = 8, 16, 24, 32, 64 FOR item IN array IFB digit <= item THEN hexInteger = strRepeat("0", VAL(item)/4 - digit) + hexInteger BREAK ENDIF NEXT totalDigits = LENGTH(hexInteger + hexDecimal) * 4 IFB digits = TRUE THEN // 桁合わせを自動調整 IFB totalDigits > 64 THEN digit = LENGTH(hexInteger + hexDecimal) WHILE LENGTH(hexInteger) > 8 AND digit > digits IFB COPY(hexInteger, 1, 1) = "0" THEN digit = digit - 1 ELSE BREAK ENDIF WEND WHILE LENGTH(hexDecimal) * 4 > 4 AND LENGTH(hexInteger + hexDecimal) > digits IFB COPY(hexDecimal, LENGTH(hexDecimal) - 1) = "0" THEN hexDecimal = COPY(hexDecimal, 1, LENGTH(hexDecimal) - 1) ELSE BREAK ENDIF WEND tmp = hexInteger + "." + hexDecimal hexInteger = COPY(tmp, 1, POS(".", tmp) - 1) hexDecimal = COPY(tmp, POS(".", tmp) + 1) totalDigits = LENGTH(hexInteger + hexDecimal) IFB totalDigits > 64 THEN isError = TRUE msg = "64bitを超えたため変換できません" ENDIF ENDIF ELSE // 指定ビットに調整 IFB totalDigits <= digits THEN hexInteger = strPad(hexInteger, digits / 4 - LENGTH(hexDecimal), "0", LEFT) ELSE // 桁あふれ調整 totalDigits = LENGTH(hexInteger + hexDecimal) digit = LENGTH(hexInteger + hexDecimal) WHILE LENGTH(hexInteger) * 4 > 8 AND digit > digits IFB COPY(hexInteger, 1, 1) = "0" THEN hexInteger = COPY(hexInteger, 2) digit = digit - 4 / 4 ELSE BREAK ENDIF WEND WHILE LENGTH(hexDecimal) * 4 > 4 AND LENGTH(hexInteger + hexDecimal) > digits IFB COPY(hexDecimal, LENGTH(hexDecimal) - 1) = "0" THEN hexDecimal = COPY(hexDecimal, 1, LENGTH(hexDecimal) - 1) ELSE BREAK ENDIF WEND tmp = hexInteger + "." + hexDecimal hexInteger = COPY(tmp, 1, POS(".", tmp) - 1) hexDecimal = COPY(tmp, POS(".", tmp) + 1) digit = LENGTH(hexInteger + hexDecimal) * 4 IFB digit > digits THEN DIM deleteLength = digit - digits IFB deleteLength = LENGTH(hexDecimal) * 4 THEN hexDecimal = "" msg = "指定ビット数にするため小数点以下を削除しました" ELSEIF deleteLength < LENGTH(hexDecimal) * 4 THEN hexDecimal = COPY(hexDecimal, 1, LENGTH(hexDecimal) - deleteLength / 4) msg = "指定ビット数にするため小数点以下の一部を削除しました" ELSE isError = TRUE msg = "指定ビット数では変換できません" ENDIF ENDIF ENDIF ENDIF hex = hexInteger + IIF(hexDecimal <> "", "." + hexDecimal, "") // (5) 入力値がマイナスのため、16進数をマイナス値に変換する IFB negativeFlg THEN bin = hexToBin(hex) // 1の補数 bin = bitNot(bin) // 2の補数 DIM res = "" DIM carry = "1" FOR i = LENGTH(bin) TO 1 STEP -1 IFB carry = "1" THEN SELECT COPY(bin, i, 1) CASE "0" res = "1" + res carry = 0 CASE "1" res = "0" + res DEFAULT res = COPY(bin, i, 1) + res SELEND ELSE res = COPY(bin, i, 1) + res ENDIF NEXT hex = binToHex(res) ENDIF ENDIF IF errorMsg AND msg <> "" THEN PRINT msg RESULT = IIF(isError, ERR_VALUE, hex) FEND ////////////////////////////////////////////////// // 【引数】 // hex : 16進数 // 【戻り値】 // 2進数に変換した値 ////////////////////////////////////////////////// FUNCTION hexToBin(hex) HASHTBL hb hb["0"] = "0000"; hb["1"] = "0001"; hb["2"] = "0010"; hb["3"] = "0011"; hb["4"] = "0100"; hb["5"] = "0101"; hb["6"] = "0110"; hb["7"] = "0111"; hb["8"] = "1000"; hb["9"] = "1001"; hb["A"] = "1010"; hb["B"] = "1011"; hb["C"] = "1100"; hb["D"] = "1101"; hb["E"] = "1110"; hb["F"] = "1111"; DIM bin = "" IFB POS(".", hex) <> 0 THEN FOR i = 1 TO LENGTH(hex) DIM str = COPY(hex, i, 1) IF str = "." THEN bin = bin + "." bin = bin + hb[str] NEXT ELSE FOR i = 1 TO LENGTH(hex) bin = bin + hb[COPY(hex, i, 1)] NEXT ENDIF RESULT = bin FEND ////////////////////////////////////////////////// // 【引数】 // hex : 16進数 // signFlg : 符号付きならばTrue // 【戻り値】 // 10進数に変換した値 ////////////////////////////////////////////////// FUNCTION hexToDec(hex, signFlg = TRUE) hex = STRCONV(hex, SC_UPPERCASE) DIM dec = 0 DIM decimalFlg = IIF(POS(".", hex) <> 0, TRUE, FALSE) hex = IIF(LENGTH(REPLACE(hex,".", "" )) MOD 2 <> 0, "0", "") + hex DIM negativeFlg = IIF(COPY(hexToBin(hex), 1, 1) = "1", TRUE, FALSE) DIM sign = 1 IF negativeFlg AND signFlg THEN sign = -1 IFB negativeFlg AND signFlg THEN DIM bin = hexToBin(hex) DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin)) DIM lsb = IIF(decimalFlg, POS(".", bin) - LENGTH(bin), 0) DIM a = hexToDec(hex, FALSE) DIM b = POWER(2, msb) - 1 FOR i = -1 TO lsb STEP -1 b = b + POWER(2, i) NEXT DIM dec2 = bitXor(a, b) + POWER(2, lsb) hex = decToHex(dec2) ENDIF integer = IIF(decimalFlg, COPY(hex, 1, POS(".", hex) - 1), hex) decimal = IIF(decimalFlg, COPY(hex, POS(".", hex) + 1), "0") FOR i = 1 TO LENGTH(integer) s = COPY(hex, i, 1) num = IIF(CHKNUM(s), s, ASC(s) - (ASC("A") - 10)) dec = dec + num * POWER(16, LENGTH(integer) - i) NEXT FOR i = 1 TO LENGTH(decimal) s = COPY(decimal, i, 1) num = IIF(CHKNUM(s), s, ASC(s) - (ASC("A") - 10)) dec = dec + num * POWER(16, -1 * i) NEXT RESULT = sign * dec FEND ////////////////////////////////////////////////// // 【引数】 // expr : 評価する式 // truepart : 評価した式がTrueのときに返す値 // falsepart : 評価した式がFalseのときに返す値 // 【戻り値】 // truepart : 評価した式がTrueのとき、falsepart : 評価した式がFalseのとき ////////////////////////////////////////////////// FUNCTION IIF(expr, truepart, falsepart) IFB EVAL(expr) THEN RESULT = truepart ELSE RESULT = falsepart ENDIF FEND ////////////////////////////////////////////////// // 【引数】 // variable : 型を調べる変数 // 【戻り値】 // : TRUE : 与えられた変数が文字列型である、 // FALSE : 与えられた変数が文字列型でない、 : ////////////////////////////////////////////////// FUNCTION isString(variable) RESULT = IIF(VARTYPE(variable) = VAR_ASTR OR VARTYPE(variable) = VAR_USTR, TRUE, FALSE) FEND ////////////////////////////////////////////////// // 【引数】 // r : 赤成分もしくは#RRGGBB形式の文字列 // g : 緑成分。rで#RRGGBB形式の文字列を指定した場合は省略。 // b : 青成分。rで#RRGGBB形式の文字列を指定した場合は省略。 // 【戻り値】 // Color値 ////////////////////////////////////////////////// FUNCTION RGBToColor(r, g = EMPTY, b = EMPTY) IFB COPY(r, 1, 1) = "#" THEN DIM color = 0 FOR i = 1 TO 3 color = color + VAL(hexToDec(COPY(r, i * 2, 2), FALSE)) * POWER(256, i - 1) NEXT RESULT = color ELSE RESULT = r + g * 256 + b * 65536 ENDIF FEND ////////////////////////////////////////////////// // 【引数】 // num : 符号を求める数値 // 【戻り値】 // 1 : 正の数、0 : ゼロ、-1 : 負の数、ERR_VALUE : それ以外 ////////////////////////////////////////////////// FUNCTION sign(num) SELECT TRUE CASE !CHKNUM(num) RESULT = ERR_VALUE CASE num > 0 RESULT = 1 CASE num = 0 RESULT = 0 CASE num < 0 RESULT = -1 SELEND FEND ////////////////////////////////////////////////// // 【引数】 // input : 入力文字列 // length : 埋めたあとの長さ // str : 埋める文字 // type : 埋める方向 // 【戻り値】 // 指定文字で埋めた文字列 ////////////////////////////////////////////////// FUNCTION strPad(input, length, str = " ", type = RIGHT) DIM s = "" SELECT type CASE LEFT FOR i = 1 TO CEIL((length - LENGTH(input)) / LENGTH(str)) s = s + str NEXT input = COPY(s, 1, length - LENGTH(input)) + input CASE RIGHT FOR i = 1 TO CEIL((length - LENGTH(input)) / LENGTH(str)) s = s + str NEXT input = input + COPY(s, 1, length - LENGTH(input)) SELEND RESULT = input FEND ////////////////////////////////////////////////// // 【引数】 // inputs : 繰り返す文字列 // multiplier : inputsを繰り返す回数 // 【戻り値】 // inputsをmultiplier回を繰り返した文字列を返します ////////////////////////////////////////////////// FUNCTION strRepeat(inputs, multiplier) DIM res = "" FOR n = 1 TO multiplier res = res + inputs NEXT RESULT = res FEND ////////////////////////////////////////////////// // 【引数】 // uwscTime : UWSC時間 // 【戻り値】 // シリアル値 ////////////////////////////////////////////////// FUNCTION uwscToSerial(uwscTime) uwscDate = uwscTime / 86400 RESULT = 36526 + uwscDate FEND
使用関数
関連記事
- now関数 (自作関数)
- 現在の日時のシリアル値を返します。
- dateValue関数 (自作関数)
- 日付形式の文字列をシリアル値に変換します。
- getYear関数 (自作関数)
- 指定された日付の年を返します。
- getMonth関数 (自作関数)
- 指定された日付の月を返します。
- getDay関数 (自作関数)
- 指定された日付の日を返します。
- getSerialTime関数 (自作関数)
- UWSC時間からシリアル値を取得します。
- uwscToSerial関数 (自作関数)
- UWSC時間をシリアル値に変換します。
- serialToUwsc関数 (自作関数)
- シリアル値をUWSC時間に変換します。
- serialToUNIX関数 (自作関数)
- シリアル値をUNIX時間に変換します。
- UNIXToSerial関数 (自作関数)
- UNIX時間 をシリアル値に変換します。