はじめに
プログラミングのあるべき未来「Live Programming」
⇒プログラミング環境としてのExcel
⇒萩谷先生の「Excelでプログラムを書く」
と見つけた先のVBAの素因数分解のプログラムが判りにくかったので、自分流に書き直してみました。
元のプログラム
1750を因数分解するために、以下の関数をワークシートに埋めていきます。
=IF(OR($A1=1,B1=""),"",IF(ROUNDDOWN($A1/B1,0)*B1=$A1,"",B1+1))
=IF(OR(A1=1,B1=""),"",OFFSET(A1,0,MATCH("",C1:AZ1,0)))
=IF(OR(A1=1,A1=""),"",A1/B2)
A | B | C | D | E | |
---|---|---|---|---|---|
1 | 1750 | 2 | |||
2 | 875 | 2 | 3 | 4 | 5 |
3 | 175 | 5 | |||
4 | 35 | 5 | 6 | 7 | |
5 | 7 | 7 | |||
6 | 1 |
「MODを使えよ。」といった突っこみはあるとして、OFFSETは無理やり使った感が否めません。
書き直したプログラム。
' 因数分解
vb.net
Function IBA(R, Optional Q = 1750, Optional S = "")
On Error Resume Next
Dim M: M = MM(R)
If M = 1 Then
S = Q
Else
S = DI(R, M - 1, 1) / DI(R, M - 1, 2)
End If
IBA = S
End Function
Function IBB(R, Optional S = "")
On Error Resume Next
Dim M: M = MM(R)
Dim A: A = DI(R, M, 1)
Dim B: If M = 1 Then B = 2 Else B = DI(R, M - 1, 2)
If PRIME(A) Then
S = A
Else
Dim I: For I = B To Int(Sqr(A))
If A Mod I = 0 Then
S = I
Exit For
End If
Next I
End If
IBB = IFC(S = 0, "", S)
End Function
Function PRIME(N, Optional S = True)
If N = 2 Then
ElseIf N = 1 Or N Mod 2 = 0 Then
S = False
Else
Dim I: For I = 3 To Int(Sqr(N)) Step 2
If N Mod I = 0 Then
S = False
Exit For
End If
Next I
End If
PRIME = S
End Function
A | B |
---|---|
=IBA(IB_) | =IBB(IB_) |
| | A | B |
|---|----|----|----|----|----|
|1 |1750| 2|||||
|2 |875 | 5|3|4|5|
|3 |175|5
|4 |35|5|6|7
|5 |7 |7
|6 |1|
まとめ
EXCELでプログラムというと、なんとかしてロジックをワークシートに収めようとしますが、
これは悪手、アンチパターンです。