本ページには広告が含まれています。
RGBの各成分、Color値、もしくは#RRGGBB形式の文字列から補色を返します。返り値は引数と同じ形式で返します。
- 構文
- Double = complementaryColor( color )
- 引数
- color 必須
- Color値
- 戻り値
- 補色
プログラム
//////////////////////////////////////////////////
// 【引数】
// color : Color値
// 【戻り値】
// 補色
//////////////////////////////////////////////////
FUNCTION complementaryColor(r, g = EMPTY, b = EMPTY)
IFB COPY(r, 1, 1) = "#" AND g = EMPTY AND b = EMPTY THEN
array = colorToRGB(RGBToColor(r))
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
DIM rgb = ""
FOR item IN array
DIM hex = decToHex(num - item)
rgb = rgb + COPY(hex, LENGTH(hex) - 1)
NEXT
RESULT = "#" + rgb
ELSEIF VAL(r) <> ERR_VALUE AND g = EMPTY AND b = EMPTY THEN
array = colorToRGB(r)
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
FOR i = 0 TO UBound(array)
array[i] = num - array[i]
NEXT
RESULT = RGBToColor(array[0], array[1], array[2])
ELSEIF VAL(r) <> ERR_VALUE AND VAL(g) <> ERR_VALUE AND VAL(b) <> ERR_VALUE THEN
DIM array[2]
array[0] = r
array[1] = g
array[2] = b
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
FOR i = 0 TO UBound(array)
array[i] = num - array[i]
NEXT
RESULT = SLICE(array)
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// color : Color値
// flg : #RRGGBB形式で返す場合Trueを指定
// 【戻り値】
// 赤成分、緑成分、青成分を格納した配列、もしくは#RRGGBB形式の文字列
//////////////////////////////////////////////////
FUNCTION colorToRGB(color, flg = FALSE)
DIM array[2]
array[0] = color AND $FF
array[1] = (color AND $FF00) / $100
array[2] = (color AND $FF0000) / $10000
IFB flg THEN
DIM rgb = ""
FOR item IN array
DIM hex = decToHex(item)
rgb = rgb + COPY(hex, LENGTH(hex)-1)
NEXT
RESULT = "#" + rgb
ELSE
RESULT = SLICE(array)
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrueを指定
// digits : 変換した2進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 2進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToBin(dec, signFlg = TRUE, digits = FALSE, recursive = 1)
IFB dec < 0 AND signFlg = FALSE THEN
RESULT = ERR_VALUE
EXIT
ENDIF
IFB VARTYPE(digits) <> VAR_BOOLEAN AND digits < CEIL(LOGN(2, ABS(dec))) + IIF(dec < 0, 1, 0) THEN
RESULT = ERR_VALUE
EXIT
ENDIF
DIM bin = ""
DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE)
DIM negativeFlg = IIF(dec < 0, TRUE, FALSE)
dec = ABS(dec)
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
REPEAT
bin = (integer MOD 2) + bin
integer = INT(integer / 2)
UNTIL integer = 0
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
WHILE loop MOD 4 <> 0
loop = loop + 1
bin = bin + "0"
WEND
ENDIF
IFB VARTYPE(digits) = VAR_BOOLEAN THEN
bin = strPad(bin, CEIL(LENGTH(REPLACE(bin, ".", "")) / 8) * 8, "0", LEFT)
ELSE
bin = strPad(bin, digits, "0", LEFT)
ENDIF
IFB negativeFlg THEN
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
DIM lsb = IIF(decimalFlg , POS(".", bin) - LENGTH(bin), 0)
DIM a = binToDec(bin, FALSE)
DIM b = POWER(2, msb) - 1
FOR i = -1 TO lsb STEP -1
b = b + POWER(2, i)
NEXT
dec = bitXor(a, b) + POWER(2, lsb)
bin = decToBin(dec, signFlg, digits, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(bin, 1, 1)
DIM len = LENGTH(REPLACE(bin, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN bin = strRepeat("1", IIF(len MOD 2 <> 0, 4, 8)) + bin
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 8 <> 0) THEN bin = strRepeat("0", IIF(len MOD 8 <> 0, 4, 8)) + bin
ENDIF
RESULT = bin
FEND
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrue
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 16進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToHex(dec, signFlg = TRUE, recursive = 1)
DIM hex = ""
DIM array[] = "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)
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
REPEAT
hex = array[integer MOD 16] + hex
integer = INT(integer / 16)
UNTIL integer = 0
IFB decimalFlg THEN
hex = hex + "."
DIM loop = 0
REPEAT
loop = loop + 1
decimal = decimal * 16
hex = hex + array[decimal]
offset = POWER(10, LENGTH(decimal) - POS(".", decimal))
decimal = (decimal * offset - INT(decimal) * offset) / offset
UNTIL decimal = 0 OR loop >= 4
ENDIF
DIM bin = hexToBin(hex)
DIM keta = LENGTH(bin)
IFB keta < 8 THEN
bin = strPad(bin, decimalFlg + 8, "0", LEFT)
ELSEIF keta < 16 THEN
bin = strPad(bin, decimalFlg + 16, "0", LEFT)
ELSEIF keta < 24 THEN
bin = strPad(bin, decimalFlg + 24, "0", LEFT)
ELSEIF keta < 32 THEN
bin = strPad(bin, decimalFlg + 32, "0", LEFT)
ELSE
bin = strPad(bin, decimalFlg + 64, "0", LEFT)
ENDIF
IFB negativeFlg THEN
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
dec = bitXor(a, b) + POWER(2, lsb)
hex = decToHex(dec, signFlg, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(hexToBin(COPY(hex, 1, 1)), 1, 1)
DIM len = LENGTH(REPLACE(hex, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN hex = strRepeat("F", IIF(len MOD 2 <> 0, 1, 2)) + hex
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 2 <> 0) THEN hex = strRepeat("0", IIF(len MOD 2 <> 0, 1, 2)) + hex
ENDIF
RESULT = 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
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// arrayname : 上限値を求める配列の名前
// dimension : 返す次元を示す整数
// 【戻り値】
// 配列の上限値
//////////////////////////////////////////////////
FUNCTION UBound(arrayname[], dimension = 1)
RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")")
FEND
解説
- 2行目
- Color値をRGBの各成分に分解し配列に格納する。
IFB COPY(r, 1, 1) = "#" AND g = EMPTY AND b = EMPTY THEN
- 3行目
- RGB値の各成分の最大値と最小値の和を求めnumに代入する。
array = colorToRGB(RGBToColor(r))
- 4行目
- numから各成分を引く。
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
- 5行目
- RGB値からColor値に変換した値を戻り値として返す。
DIM rgb = ""
プログラム実行例
ビットマップ画像を補色に変換(24ビット)
PUBLIC item
PUBLIC count
PUBLIC starttime
PUBLIC bool = FALSE
CONST adTypeBinary = 1
DIM path = "D:\Desktop\UWSC\d22.bmp"
DIM array = getBitmap(path)
DIM width = array[1]
DIM height = array[2]
DIM Stream = CREATEOLEOBJ("ADODB.Stream")
WITH Stream
.Open()
.Type = adTypeBinary
.LoadFromFile(path)
DIM tmp = .Read(-1)
.Close()
ENDWITH
THREAD progress()
starttime = text(now(), "yyyy/mm/dd hh:nn:ss")
count = width * height
FOR h = 0 TO height-1
FOR w = 0 TO width
item = w + width * h
i = 54 + w * 3 + (h * (width+1) * 3)
col = ""
FOR rgb = 0 TO 2
ii = i + rgb
TRY
hex = decToHex(tmp[ii])
EXCEPT
BREAK 2
ENDTRY
col = col + IIF(LENGTH(hex) = 1, "0", "") + hex
NEXT
color = hexToDec(col)
comp = complementaryColor(color)
comp = decToHex(comp)
FOR rgb = 0 TO 2
tmp[i + rgb] = hexToDec(COPY(comp, rgb * 2 + 1, 2))
NEXT
NEXT
PRINT
NEXT
bool = TRUE
WITH Stream
.Open()
.Type = adTypeBinary
.Write(tmp)
DIM FSO = CREATEOLEOBJ("Scripting.FileSystemObject")
DIM folderspec = FSO.GetParentFolderName(path)
DIM filename = FSO.GetBaseName(path)
DIM extension = FSO.GetExtensionName(path)
path = folderspec + "\" + filename + "_comp." + extension
.SaveToFile(uniqueFilename(path))
.Close()
ENDWITH
PROCEDURE progress()
REPEAT
DIM elapsedTime = GETTIME() - GETTIME(0, starttime)
DIM ratio = item / count
time = elapsedTime / ratio
FUKIDASI("開始時刻<#TAB>" + starttime + "<#CR>" + _
"経過時間<#TAB>" + text(elapsedTime/86400, "hh:nn:ss") + "<#CR>" + _
"進捗率<#TAB><#TAB>" + ROUND(ratio * 100, -5) + "%<#CR>" + _
"項目数<#TAB><#TAB>" + item + "/" + count + "<#CR>" + _
"残り時間<#TAB>" + IIF(INT((time-elapsedTime)/86400) <> 0, INT((time-elapsedTime)/86400) + "日", "") + text((time-elapsedTime)/86400, "hh:nn:ss") + "<#CR>" + _
"終了予定時刻<#TAB>" + IIF(item = "" OR starttime = "", "∞", dateAdd("s", time, starttime)), 0, 0)
SLEEP(0.001)
UNTIL bool
FEND
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// color : Color値
// flg : #RRGGBB形式で返す場合Trueを指定
// 【戻り値】
// 赤成分、緑成分、青成分を格納した配列、もしくは#RRGGBB形式の文字列
//////////////////////////////////////////////////
FUNCTION colorToRGB(color, flg = FALSE)
DIM array[2]
array[0] = color AND $FF
array[1] = (color AND $FF00) / $100
array[2] = (color AND $FF0000) / $10000
IFB flg THEN
DIM rgb = ""
FOR item IN array
DIM hex = decToHex(item)
rgb = rgb + COPY(hex, LENGTH(hex)-1)
NEXT
RESULT = "#" + rgb
ELSE
RESULT = SLICE(array)
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
// color : Color値
// 【戻り値】
// 補色
//////////////////////////////////////////////////
FUNCTION complementaryColor(r, g = EMPTY, b = EMPTY)
IFB COPY(r, 1, 1) = "#" AND g = EMPTY AND b = EMPTY THEN
array = colorToRGB(RGBToColor(r))
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
DIM rgb = ""
FOR item IN array
DIM hex = decToHex(num - item)
rgb = rgb + COPY(hex, LENGTH(hex) - 1)
NEXT
RESULT = "#" + rgb
ELSEIF VAL(r) <> ERR_VALUE AND g = EMPTY AND b = EMPTY THEN
array = colorToRGB(r)
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
FOR i = 0 TO UBound(array)
array[i] = num - array[i]
NEXT
RESULT = RGBToColor(array[0], array[1], array[2])
ELSEIF VAL(r) <> ERR_VALUE AND VAL(g) <> ERR_VALUE AND VAL(b) <> ERR_VALUE THEN
DIM array[2]
array[0] = r
array[1] = g
array[2] = b
num = CALCARRAY(array, CALC_MAX) + CALCARRAY(array, CALC_MIN)
FOR i = 0 TO UBound(array)
array[i] = num - array[i]
NEXT
RESULT = SLICE(array)
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
// interval : 加算する時間間隔を表す文字列式(yyyy:年、m:月、d:日、ww:週、h:時、n:分、s:秒)
// num : dateに加算する値。未来は正、過去は負で指定
// date : 時間間隔を加算する日付
// 【戻り値】
// 日時(date)に、指定した単位(interval)の時間(num)を加算して返します
//////////////////////////////////////////////////
FUNCTION dateAdd(interval, num, date)
DIM year, month, day, d
GETTIME(0, date)
DIM time = G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2
SELECT interval
CASE "yyyy"
d = (G_TIME_YY + num) + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
IF time <> "00:00:00" THEN d = d + " " + time
CASE "m"
IFB num > 0 THEN
year = G_TIME_YY + INT((G_TIME_MM + num) / 12)
month = REPLACE(FORMAT(((G_TIME_MM + num) MOD 12), 2), " ", "0")
ELSE
year = G_TIME_YY + CEIL((G_TIME_MM + num) / 12 - 1)
month = REPLACE(FORMAT(G_TIME_MM - (ABS(num) MOD 12), 2), " ", "0")
ENDIF
IF month = "00" THEN month = 12
day = G_TIME_DD2
d = "" + year + month + day
IFB !isDate(d) THEN
d = year + "/" + month + "/" + "01"
d = getEndOfMonth(d)
ELSE
d = year + "/" + month + "/" + day
ENDIF
IF time <> "00:00:00" THEN d = d + " " + time
CASE "d"
t = GETTIME(num, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
CASE "ww"
t = GETTIME(num * 7, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
CASE "h"
t = GETTIME(num / 24, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
CASE "n"
t = GETTIME(num / 1440, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
CASE "s"
t = GETTIME(num / 86400, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
SELEND
RESULT = d
FEND
//////////////////////////////////////////////////
// 【引数】
// interval : 時間単位(yyyy︰年、q:四半期、m︰月、d︰日、w:週日、ww:週、h:時、n:分、s:秒)
// date1 : 日時1
// date2 : 日時2
// 【戻り値】
// date2からdate1を引いた時間間隔を求めます。
//////////////////////////////////////////////////
FUNCTION dateDiff(interval, date1, date2)
DIM y1, y2, m1, m2, d1, d2, d
SELECT interval
CASE "yyyy"
GETTIME(0, date1)
y1 = G_TIME_YY
GETTIME(0, date2)
y2 = G_TIME_YY
d = y2 - y1
CASE "q"
GETTIME(0, date1)
y1 = G_TIME_YY
m1 = G_TIME_MM
GETTIME(0, date2)
y2 = G_TIME_YY
m2 = G_TIME_MM
d = y2 * 4 + CEIL(m2/3) - (y1 * 4 + CEIL(m1/3))
CASE "m"
GETTIME(0, date1)
y1 = G_TIME_YY
m1 = G_TIME_MM
GETTIME(0, date2)
y2 = G_TIME_YY
m2 = G_TIME_MM
d = (y2 - y1) * 12 + m2 - m1
CASE "d"
d1 = GETTIME(0, date1)
d2 = GETTIME(0, date2)
d = (d2 - d1) / 86400
CASE "w"
d = INT(dateDiff("d", date1, date2) / 7)
CASE "ww"
date1 = dateAdd("d", -1 * getWeekday(date1), date1)
d = INT(dateDiff("d", date1, date2) / 7)
CASE "h"
d = dateDiff("d", date1, date2) * 24
CASE "n"
d = dateDiff("d", date1, date2) * 1440
CASE "s"
d = dateDiff("d", date1, date2) * 86400
SELEND
RESULT = d
FEND
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrueを指定
// digits : 変換した2進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 2進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToBin(dec, signFlg = TRUE, digits = FALSE, recursive = 1)
IFB dec < 0 AND signFlg = FALSE THEN
RESULT = ERR_VALUE
EXIT
ENDIF
IFB VARTYPE(digits) <> VAR_BOOLEAN AND digits < CEIL(LOGN(2, ABS(dec))) + IIF(dec < 0, 1, 0) THEN
RESULT = ERR_VALUE
EXIT
ENDIF
DIM bin = ""
DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE)
DIM negativeFlg = IIF(dec < 0, TRUE, FALSE)
dec = ABS(dec)
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
REPEAT
bin = (integer MOD 2) + bin
integer = INT(integer / 2)
UNTIL integer = 0
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
WHILE loop MOD 4 <> 0
loop = loop + 1
bin = bin + "0"
WEND
ENDIF
IFB VARTYPE(digits) = VAR_BOOLEAN THEN
bin = strPad(bin, CEIL(LENGTH(REPLACE(bin, ".", "")) / 8) * 8, "0", LEFT)
ELSE
bin = strPad(bin, digits, "0", LEFT)
ENDIF
IFB negativeFlg THEN
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
DIM lsb = IIF(decimalFlg , POS(".", bin) - LENGTH(bin), 0)
DIM a = binToDec(bin, FALSE)
DIM b = POWER(2, msb) - 1
FOR i = -1 TO lsb STEP -1
b = b + POWER(2, i)
NEXT
dec = bitXor(a, b) + POWER(2, lsb)
bin = decToBin(dec, signFlg, digits, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(bin, 1, 1)
DIM len = LENGTH(REPLACE(bin, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN bin = strRepeat("1", IIF(len MOD 2 <> 0, 4, 8)) + bin
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 8 <> 0) THEN bin = strRepeat("0", IIF(len MOD 8 <> 0, 4, 8)) + bin
ENDIF
RESULT = bin
FEND
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrue
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 16進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToHex(dec, signFlg = TRUE, recursive = 1)
DIM hex = ""
DIM array[] = "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)
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
REPEAT
hex = array[integer MOD 16] + hex
integer = INT(integer / 16)
UNTIL integer = 0
IFB decimalFlg THEN
hex = hex + "."
DIM loop = 0
REPEAT
loop = loop + 1
decimal = decimal * 16
hex = hex + array[decimal]
offset = POWER(10, LENGTH(decimal) - POS(".", decimal))
decimal = (decimal * offset - INT(decimal) * offset) / offset
UNTIL decimal = 0 OR loop >= 4
ENDIF
DIM bin = hexToBin(hex)
DIM keta = LENGTH(bin)
IFB keta < 8 THEN
bin = strPad(bin, decimalFlg + 8, "0", LEFT)
ELSEIF keta < 16 THEN
bin = strPad(bin, decimalFlg + 16, "0", LEFT)
ELSEIF keta < 24 THEN
bin = strPad(bin, decimalFlg + 24, "0", LEFT)
ELSEIF keta < 32 THEN
bin = strPad(bin, decimalFlg + 32, "0", LEFT)
ELSE
bin = strPad(bin, decimalFlg + 64, "0", LEFT)
ENDIF
IFB negativeFlg THEN
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
dec = bitXor(a, b) + POWER(2, lsb)
hex = decToHex(dec, signFlg, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(hexToBin(COPY(hex, 1, 1)), 1, 1)
DIM len = LENGTH(REPLACE(hex, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN hex = strRepeat("F", IIF(len MOD 2 <> 0, 1, 2)) + hex
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 2 <> 0) THEN hex = strRepeat("0", IIF(len MOD 2 <> 0, 1, 2)) + hex
ENDIF
RESULT = hex
FEND
//////////////////////////////////////////////////
// 【引数】
// str : 相互変換させるバイナリデータ
// 【戻り値】
// 変換したバイナリデータ
//////////////////////////////////////////////////
FUNCTION Endian(str)
DIM len = LENGTH(str)
IFB !isEven(len) THEN
str = "0" + str
len = len + 1
ENDIF
DIM res = ""
FOR n = 1 TO len STEP 2
res = COPY(str, n, 2) + res
NEXT
RESULT = res
FEND
//////////////////////////////////////////////////
// 【引数】
// array : 最大公約数を求める数値を格納した配列
// 【戻り値】
// 最大公約数
//////////////////////////////////////////////////
FUNCTION GCD(array[])
DIM c = LENGTH(array)
DIM rem = array[c-1] MOD array[c-2]
IFB rem = 0 THEN
IFB LENGTH(array) = 2 THEN
RESULT = array[c-2]
EXIT
ENDIF
RESIZE(array, c-2)
RESULT = GCD(array)
EXIT
ENDIF
array[c-1] = array[c-2]
array[c-2] = rem
RESULT = GCD(array)
FEND
//////////////////////////////////////////////////
// 【引数】
// path : ビットマップ画像のパス
// 【戻り値】
// 配列。0:サイズ(Byte)、1:幅(px)、2:高さ(px)、3:ビットの深さ(bit)
//////////////////////////////////////////////////
FUNCTION getBitmap(path)
CONST adTypeBinary = 1
DIM array[3]
DIM Stream = CREATEOLEOBJ("ADODB.Stream")
Stream.Open()
Stream.Type = adTypeBinary
Stream.LoadFromFile(path)
DIM tmp = Stream.Read(30)
Stream.Close()
DIM fmt = ""
FOR i = 0 TO 1
fmt = fmt + decToHex(tmp[i])
NEXT
IFB fmt <> "424D" THEN
RESULT = ERR_VALUE
EXIT
ENDIF
DIM size = ""
FOR i = 2 TO 5
hex = decToHex(tmp[i], FALSE)
size = size + IIF(LENGTH(hex) = 1, "0", "") + hex
NEXT
array[0] = hexToDec(Endian(size))
DIM width = ""
FOR i = 18 TO 21
hex = decToHex(tmp[i], FALSE)
width = width + IIF(LENGTH(hex) = 1, "0", "") + hex
NEXT
array[1] = hexToDec(Endian(width))
DIM height = ""
FOR i = 22 TO 25
hex = decToHex(tmp[i], FALSE)
height = height + IIF(LENGTH(hex) = 1, "0", "") + hex
NEXT
array[2] = hexToDec(Endian(height))
DIM bit = ""
FOR i = 28 TO 29
hex = decToHex(tmp[i], FALSE)
bit = bit + IIF(LENGTH(hex) = 1, "0", "") + hex
NEXT
array[3] = hexToDec(Endian(bit))
RESULT = SLICE(array)
FEND
//////////////////////////////////////////////////
// 【引数】
// date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”)
// m : 第一引数の指定日からプラスマイナスm月とする
// 【戻り値】
// dateからm月後の月末の日付
//////////////////////////////////////////////////
FUNCTION getEndOfMonth(date, m = 0)
date = dateAdd("m", m + 1, date)
GETTIME(0, date)
GETTIME(-G_TIME_DD, date)
RESULT = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
FEND
//////////////////////////////////////////////////
// 【引数】
// date : 日付文字列(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”)もしくはシリアル値
// type : 取得する曜日番号の種類を示す0〜3または11〜17の値。1と17は日曜日を1、2と11は月曜日を1とカウントします。11以降はExcel2010で追加された値で、互換性を保つために重複した値があります。
// 【戻り値】
// typeで指定した種類によって以下の値を返します。 : (0 : 0(日曜)〜6(土曜)、1 : 1(日曜)~7(土曜)、2 : 1(月曜)~7(日曜)、3 : 0(月曜)〜6(日曜)、11 : 1(月曜)~7(日曜)、12 : 1(火曜)~7(月曜)、13 : 1(水曜)~7(火曜)、14 : 1(木曜)~7(水曜)、15 : 1(金曜)~7(木曜)、16 : 1(土曜)~7(金曜)、17 : 1(日曜)~7(土曜))
//////////////////////////////////////////////////
FUNCTION getWeekday(date, type = 1)
IF VARTYPE(date) <> 258 THEN date = text(date, "yyyy/mm/dd")
GETTIME(0, date)
DIM w = G_TIME_WW
SELECT TRUE
CASE type = 0
RESULT = w
CASE type = 1
RESULT = w + 1
CASE type = 2
RESULT = IIF(w=0, 7, w)
CASE type = 3
RESULT = (w+6) MOD 7
CASE type >= 11
RESULT = ((getWeekday(date, 2) + 17 - type) MOD 7) + 1
SELEND
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
//////////////////////////////////////////////////
// 【引数】
// serial : シリアル値もしくは時刻文字列
// 【戻り値】
// 時刻から時間を表す0〜23の範囲の値
//////////////////////////////////////////////////
FUNCTION Hour(serial)
IF VARTYPE(serial) = 258 THEN serial = timeValue(serial)
RESULT = INT(serial * 24) MOD 24
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
//////////////////////////////////////////////////
// 【引数】
// date : 存在するかを調べる日付文字列。YYYYMMDD or YYYY/MM/DD or YYYY-MM-DDのいずれかの形式。
// 【戻り値】
// TRUE : 日付として認識できる、FALSE : 日付として認識できない
//////////////////////////////////////////////////
FUNCTION isDate(date)
TRY
GETTIME(0, date)
RESULT = TRUE
EXCEPT
RESULT = FALSE
ENDTRY
FEND
//////////////////////////////////////////////////
// 【引数】
// 数値 : 整数
// 【戻り値】
// True : 偶数、False : 偶数以外の数値、ERR_VALUE : 数値以外
//////////////////////////////////////////////////
FUNCTION isEven(n)
IFB VAL(n) = n THEN
RESULT = IIF(INT(n) MOD 2 = 0, TRUE, FALSE)
ELSE
RESULT = ERR_VALUE
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
//
// 【戻り値】
//
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// 【引数】
// str : 正規表現による検索の対象となる文字列
// Pattern : 正規表現で使用するパターンを設定
// IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse
// Global : 文字列全体を検索する場合はTrue、しない場合はFalse
// 【戻り値】
// 正規表現で検索した結果をMatchesコレクションとして返します。
//////////////////////////////////////////////////
FUNCTION reExecute(str, Pattern, IgnoreCase = TRUE, Global = TRUE)
DIM re = CREATEOLEOBJ("VBScript.RegExp")
re.Pattern = Pattern
re.IgnoreCase = IgnoreCase
re.Global = Global
RESULT = re.Execute(str)
FEND
//////////////////////////////////////////////////
// 【引数】
// str : 正規表現による検索の対象となる文字列
// Pattern : 正規表現で使用するパターンを設定
// IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse
// Global : 文字列全体を検索する場合はTrue、しない場合はFalse
// 【戻り値】
// 正規表現にマッチするかどうかを示すブール値
//////////////////////////////////////////////////
FUNCTION reTest(str, Pattern, IgnoreCase = TRUE, Global = TRUE)
DIM re = CREATEOLEOBJ("VBScript.RegExp")
re.Pattern = Pattern
re.IgnoreCase = IgnoreCase
re.Global = Global
RESULT = re.Test(str)
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
//////////////////////////////////////////////////
// 【引数】
// serial : シリアル値
// format : フォーマット
// 【戻り値】
// 数値を表示書式に基づいて変換した文字列
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// 【引数】
// serial : シリアル値
// format : フォーマット
// 【戻り値】
//
//////////////////////////////////////////////////
FUNCTION text(serial, format, hour12 = FALSE)
HASHTBL startDate
startDate["明治"] = "1868/01/25"
startDate["大正"] = "1912/07/30"
startDate["昭和"] = "1926/12/25"
startDate["平成"] = "1989/01/08"
startDate["令和"] = "2019/05/01"
DIM baseDate = "1899/12/30"
serial = VAL(serial)
SELECT TRUE
CASE reTest(format, "\[h+\]")
Matches = reExecute(format, "\[(h+)\]")
DIM hour = iif(hour12, Hour(serial) MOD 12, Hour(serial))
RESULT = text(hour, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0))))
CASE reTest(format, "^h+$")
Matches = reExecute(format, "^(h+)$")
hour = iif(hour12, Hour(serial) MOD 12, Hour(serial))
RESULT = text(hour MOD 24, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0))))
CASE reTest(format, "\[m+\]")
Matches = reExecute(format, "\[(m+)\]")
RESULT = text(serial * 1440, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0))))
CASE format = "m"
GETTIME(serial, baseDate)
RESULT = text(G_TIME_MM, "0")
CASE format = "mm"
GETTIME(serial, baseDate)
RESULT = G_TIME_MM2
CASE format = "n"
GETTIME(serial, baseDate)
RESULT = G_TIME_NN
CASE format = "nn"
GETTIME(serial, baseDate)
RESULT = G_TIME_NN2
CASE format = "s"
GETTIME(serial, baseDate)
RESULT = text(G_TIME_SS, "0")
CASE format = "ss"
GETTIME(serial, baseDate)
RESULT = G_TIME_SS2
CASE format = "yyyy"
GETTIME(serial, baseDate)
RESULT = G_TIME_YY4
CASE format = "yy"
GETTIME(serial, baseDate)
RESULT = COPY(G_TIME_YY4, 3, 2)
CASE format = "e"
SELECT TRUE
CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(serial, "yyyy") - 2018
CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(serial, "yyyy") - 1988
CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(serial, "yyyy") - 1925
CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(serial, "yyyy") - 1911
CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(serial, "yyyy") - 1867
SELEND
CASE format = "ee"
SELECT TRUE
CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(text(serial, "yyyy") - 2018, "00")
CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(text(serial, "yyyy") - 1988, "00")
CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(text(serial, "yyyy") - 1925, "00")
CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(text(serial, "yyyy") - 1911, "00")
CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0
RESULT = text(text(serial, "yyyy") - 1867, "00")
SELEND
CASE format = "g"
SELECT TRUE
CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "R"
CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "H"
CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "S"
CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "T"
CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "M"
SELEND
CASE format = "gg"
RESULT = COPY(text(serial, "ggg"), 1, 1)
CASE format = "ggg"
SELECT TRUE
CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "令和"
CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "平成"
CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "昭和"
CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "大正"
CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "明治"
SELEND
CASE format = "mmmmm"
RESULT = COPY(text(serial, "mmmm"), 1, 1)
CASE format = "mmmm"
DIM month[] = "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
RESULT = month[text(serial, "m") - 1]
CASE format = "mmm"
RESULT = COPY(text(serial, "mmmm"), 1, 3)
CASE format = "dd"
GETTIME(serial, baseDate)
RESULT = text(G_TIME_DD2, "00")
CASE format = "d"
GETTIME(serial, baseDate)
RESULT = text(G_TIME_DD, "0")
CASE reTest(format, "^[ad]{3,4}$")
Matches = reExecute(format, "([ad]{3,4})")
GETTIME(serial, baseDate)
DIM aaa[] = "日", "月", "火", "水", "木", "金", "土"
DIM aaaa[] = "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"
DIM ddd[] = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
DIM dddd[] = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday";
RESULT = EVAL(Matches.Item(0).SubMatches(0) + "[" + getWeekday(G_TIME_WW, 1) + "]")
CASE reTest(format, "(0+\.?0+)?%")
Matches = reExecute(format, "(0+\.?0+)?%")
RESULT = text(serial * 100, Matches.Item(0).SubMatches(0)) + "%"
CASE reTest(format, "^\[DBNum\d{1,4}\](.*?)$")
Matches = reExecute(format, "^\[DBNum(\d{1,4})\](.*?)$")
DIM value = VAL(Matches.Item(0).SubMatches(0))
DIM sss = text(serial, Matches.Item(0).SubMatches(1))
Matches = reExecute(sss, "(\D+)?(\d+)(\D+)?")
DIM res = ""
FOR m = 0 TO Matches.Count - 1
serial = Matches.Item(m).SubMatches(1)
SELECT value
CASE 1, 2
DIM n[][9] = "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", + _
"", "壱", "弐", "参", "四", "伍", "六", "七", "八", "九"
DIM a[][3] = "", "十", "百", "千", + _
"", "拾", "百", "阡"
DIM b[][3] = "", "万", "億", "兆", + _
"", "萬", "億", "兆"
DIM r = ""
DIM j = 0
type = value - 1
REPEAT
DIM str = ""
DIM n4 = serial MOD 10000
FOR i = LENGTH(n4) TO 1 STEP -1
s = COPY(n4, i, 1)
IFB s = 1 AND a[type][LENGTH(n4)-i] <> "" THEN
str = IIF(s, a[type][LENGTH(n4)-i], "") + str
ELSE
str = n[type][s] + IIF(s, a[type][LENGTH(n4)-i], "") + str
ENDIF
NEXT
IF str <> "" THEN r = str + b[type][j] + r
j = j + 1
serial = INT(serial / 10000)
UNTIL serial = 0
res = res + Matches.Item(m).SubMatches(0) + r + Matches.Item(m).SubMatches(2)
CASE 3
res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_FULLWIDTH) + Matches.Item(m).SubMatches(2)
CASE 4
res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_HALFWIDTH) + Matches.Item(m).SubMatches(2)
SELEND
NEXT
RESULT = res
CASE reTest(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$")
Matches = reExecute(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$")
DIM array = SPLIT(Matches.Item(0).SubMatches(1), "/")
ampm = array[IIF(serial - INT(serial) >= 0.5, 1, 0)]
hour12 = TRUE
res = ""
WITH Matches.Item(0)
res = text(serial, .SubMatches(0), hour12) + ampm + text(serial, .SubMatches(2), hour12)
ENDWITH
RESULT = res
CASE reTest(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?")
Matches = reExecute(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?")
FOR n = 0 TO Matches.Count - 1
IF n = 0 THEN res = Matches.Item(n).SubMatches(0)
NEXT
FOR n = 0 TO Matches.Count - 1
WITH Matches.Item(n)
res = res + text(serial, .SubMatches(1), hour12) + .SubMatches(3)
ENDWITH
NEXT
RESULT = res
CASE format = "0/0"
DIM separator = POS(".", serial)
DIM g = 0
IFB separator <> 0 THEN
DIM keta = LENGTH(serial)
DIM shift = POWER(10, keta - separator)
IFB shift >= POWER(10, 15) THEN
DIM position = 0
FOR i = 0 TO 14
IFB serial * POWER(10, i) - serial >= 1 THEN
position = i
BREAK
ENDIF
NEXT
tmp = serial * POWER(10, position)
FOR i = 1 TO 15
r = (tmp * POWER(10, i)) / serial - (tmp / serial)
a1 = tmp * POWER(10, i) - tmp
IF a1 = INT(a1) THEN BREAK
NEXT
DIM frac[] = a1, r
g = GCD(frac)
RESULT = (a1/g) + "/" + (r/g)
ELSE
DIM molecule = serial * shift // 分子
DIM denominator = shift // 分母
DIM nums[] = molecule, denominator
g = GCD(nums)
molecule = molecule / g
denominator = denominator / g
RESULT = molecule + "/" + denominator
ENDIF
ELSE
RESULT = serial + "/1"
ENDIF
CASE reTest(format, "(0+)\.?(0+)?") AND UBound(SPLIT(format, ".")) <= 1
Matches = reExecute(format, "(0+)\.?(0+)?")
len1 = LENGTH(Matches.Item(0).SubMatches(0))
len2 = LENGTH(Matches.Item(0).SubMatches(1))
DIM arr[] = LENGTH(INT(serial)), len1
IFB POS(".", format) THEN
RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX) + len2 + 1, len2), " ", "0")
ELSE
RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX)), " ", "0")
ENDIF
SELEND
FEND
//////////////////////////////////////////////////
// 【引数】
// str : 時刻文字列。hh:nn:ss AM/PM、hh:nn AM/PM、hh AM/PM、hh:nn:ss、hh:nn、hh時nn分ss秒、hh時nn分のいずれかの形式を指定。
// 【戻り値】
// シリアル値 (例)0…00:00:00、0.5…12:00:00、0.999988425925926…23:59:59
//////////////////////////////////////////////////
FUNCTION timeValue(str)
DIM serial = 0
DIM Matches
DIM pattern = "(\d+)"
DIM hh = "(0?[0-9]|1[0-2])"
DIM ampm = "([AP]M|[ap]m)"
SELECT TRUE
CASE reTest(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b")
Matches = reExecute(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b")
WITH Matches.Item(0)
serial = timeValue(.SubMatches(0) + " " + .SubMatches(3)) + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400
ENDWITH
CASE reTest(str, "\b" + hh + ":" + pattern + " " + ampm + "\b")
Matches = reExecute(str, "\b" + hh + ":" + pattern + " " + ampm + "\b")
WITH Matches.Item(0)
serial = timeValue(.SubMatches(0) + " " + .SubMatches(2)) + VAL(.SubMatches(1)) / 1440
ENDWITH
CASE reTest(str, "\b" + hh + " " + ampm + "\b")
Matches = reExecute(str, "\b" + hh + " " + ampm + "\b")
WITH Matches.Item(0)
serial = VAL(.SubMatches(0) MOD 12) + IIF(reTest(.SubMatches(1), "AM|am"), 0, 12)
serial = serial / 24
ENDWITH
CASE reTest(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b")
Matches = reExecute(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b")
WITH Matches.Item(0)
serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400
ENDWITH
CASE reTest(str, "\b" + pattern + ":" + pattern + "\b")
Matches = reExecute(str, "\b" + pattern + ":" + pattern + "\b")
WITH Matches.Item(0)
serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440
ENDWITH
CASE reTest(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒")
Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒")
WITH Matches.Item(0)
serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400
ENDWITH
CASE reTest(str, "\b" + pattern + "時" + pattern + "分")
Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分")
WITH Matches.Item(0)
serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440
ENDWITH
DEFAULT
serial = ERR_VALUE
SELEND
RESULT = serial - INT(serial)
FEND
//////////////////////////////////////////////////
// 【引数】
// arrayname : 上限値を求める配列の名前
// dimension : 返す次元を示す整数
// 【戻り値】
// 配列の上限値
//////////////////////////////////////////////////
FUNCTION UBound(arrayname[], dimension = 1)
RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")")
FEND
//////////////////////////////////////////////////
// 【引数】
// path : ファイルのパス
// 【戻り値】
// 重複しないファイル名
//////////////////////////////////////////////////
FUNCTION uniqueFilename(path)
DIM FSO = CREATEOLEOBJ("Scripting.FileSystemObject")
IFB FSO.FileExists(path) THEN
DIM fol = FSO.GetParentFolderName(path)
DIM filename = FSO.GetBaseName(path)
DIM extension = FSO.GetExtensionName(path)
DIM i = 2
WHILE FSO.FileExists(FSO.BuildPath(fol, filename + " (" + i + ")." + extension))
i = i + 1
WEND
RESULT = FSO.BuildPath(fol, filename + " (" + i + ")." + extension)
ELSE
RESULT = path
ENDIF
FEND
使用関数
解説
関連記事
- CHKIMG関数 (スクリプト関数)
- 指定画像が画面上にあるかチェックしあればその情報を返します。
- Borders.Color プロパティ (Excel)
- 罫線の色を取得または設定する。
- invertedColor関数 (自作関数)
- RGBの各成分、Color値、もしくは#RRGGBB形式の文字列から反転色を返します。返り値は引数と同じ形式で返します。
- colorToRGB関数 (自作関数)
- Color値を赤成分、緑成分、青成分に分解し格納した配列で返します。各成分は10進数の値で表されます。flgにTrueを指定した場合、#RRGGBBの形式で返します。
- RGBToColor関数 (自作関数)
- 引数に指定された赤成分、緑成分、青成分、もしくは#RRGGBB形式の文字列からColor値を求めます。
- BGRToColor関数 (自作関数)
- 引数に指定された青成分、緑成分、赤成分、もしくは#BBGGRR形式の文字列からColor値を求めます。
- PEEKCOLOR関数 (スクリプト関数)
- PEEKCOLOR関数は、指定座標の色を取得する関数です。
- colorToBGR関数 (自作関数)
- Color値を青成分、緑成分、赤成分に分解し格納した配列で返します。各成分は10進数の値で表されます。flgにTrueを指定した場合、#BBGGRRの形式で返します。