タイトルの質問だけでは意図する意味が分からないと思うので
例を書きます。
①のプログラム
vba
1If A > B And C > D Then 2 Call setMsg("ありがとう") 3ElseIf A > B And C < D Then 4 Call setMsg("ありがとう") 5ElseIf A < B And C > D Then 6 Call setMsg("ありがとう") 7ElseIf A < B And C < D Then 8 Call setMsg("thank you") 9End If
例えばこんな分岐があったとして、
書き換える方法はいくらでもあると思うのですが、
書き換え1
②のプログラム
vba
1If A > B Then 2 Call setMsg("ありがとう") 3ElseIf C > D Then 4 Call setMsg("ありがとう") 5Else 6 Call setMsg("thank you") 7End If
書き換え2
③のプログラム
vba
1If (A > B And C > D) Or (A > B And C < D) Or (A < B And C > D) Then 2 Call setMsg("ありがとう") 3Else 4 Call setMsg("thank you") 5End If
①は分岐パターンを4つすべてIfで描いたことで、
分岐の論理はわかりやすいですが、結果セットが同じものが複数できていて、
冗長的に思えますよね。
②は分岐パターンが多少工夫され、
パターンは減りましたが、結果セットは同じ組み合わせがあるし、
パターン網羅されているかどうかは、①に比べてわかりにくくなった気がしますよね?
③は確かに分岐パターンが二分化されていて、結果セットはそれぞれのパターンのみに集約されていますが、
If分の構成が長く見ずらい印象を持ちますよね。
こうなった場合、皆様はどんな工夫を凝らして、
スマートなコードを書いていますか。
教えてください。
回答をいただいたので例文追加で、説明を求めます。
vba
1Sub CellSetter() 2 For i = 6 To rowsCount 3 '作業着手予定日が空ならFor文から抜ける 4 If Cells(i, 2).Value = "" Then 5 Exit For 6 End If 7 'B6セルから末端までのデータを一時的に格納する。 8 cellDateB = Cells(i, 2).Value 9 'C6セルから末端までのデータを一時的に格納する。 10 cellDateC = Cells(i, 3).Value 11 'D6セルから末端までのデータを一時的に格納する。 12 cellDataD = Cells(i, 4).Value 13 '① 14 If cellDateC < cellDateFrom Then 15 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 16 '② 17 ElseIf cellDateB < cellDateFrom And cellDateC = cellDateTo Then 18 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 19 '③ 20 ElseIf cellDateB < cellDateFrom And cellDateFrom < cellDateC And cellDateC < cellDateTo Then 21 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 22 '④ 23 ElseIf cellDateFrom = cellDateB And cellDateFrom < cellDateC And cellDateC < cellDateTo Then 24 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 25 '⑤ 26 ElseIf cellDateFrom < cellDateB And cellDateB < cellDateTo And cellDateFrom < cellDateC And cellDateC < cellDateTo Then 27 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 28 '⑥ 29 ElseIf cellDateFrom < cellDateB And cellDateB < cellDateTo And cellDateC = cellDateTo Then 30 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 31 '⑦ 32 ElseIf cellDateFrom < cellDateB And cellDateB < cellDateTo And cellDateTo < cellDateC Then 33 Call Selecter(i, cellDataD, C_START, C_END_FIRST, C_START, C_END_EMP, C_START_LATE, C_END_EMP) 34 '⑧ 35 ElseIf cellDateB = cellDateTo And cellDateTo < cellDateC Then 36 Call Selecter(i, cellDataD, C_START, C_END_FIRST, C_START, C_END_EMP, C_START_LATE, C_END_EMP) 37 '⑨ 38 ElseIf cellDateTo < cellDateB Then 39 Call Selecter(i, cellDataD, C_START_FIRST, C_END_FIRST, C_START_FIRST, C_END_EMP, C_START_EMP, C_END_EMP) 40 '⑩ 41 ElseIf cellDateB < cellDateFrom And cellDateFrom = cellDateC Then 42 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 43 '⑪ 44 ElseIf cellDateB = cellDateFrom And cellDateC = cellDateTo Then 45 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 46 '⑫ 47 ElseIf cellDateB = cellDateFrom And cellDateTo < cellDateC Then 48 Call Selecter(i, cellDataD, C_START, C_END_FIRST, C_START, C_END_EMP, C_START_LATE, C_END_EMP) 49 '⑬ 50 ElseIf cellDateB < cellDateFrom And cellDateTo < cellDateC Then 51 Call Selecter(i, cellDataD, C_START, C_END_FIRST, C_START, C_END_EMP, C_START_LATE, C_END_EMP) 52 '⑭ 53 ElseIf cellDateB = cellDateFrom And cellDateC = cellDateFrom Then 54 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 55 '⑮ 56 ElseIf cellDateB = cellDateTo And cellDateC = cellDateTo Then 57 Call Selecter(i, cellDataD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 58 End If 59 Next i 60 End Sub
このプログラムで分岐結果が少ないのは⑨の一個ですが、
vba
1If cellDateTo < cellDateB Then 2 '処理 3ElseIf
とした後のElseIfの式はどうかきますか?
BA後のコメントに対してさらに改修したコード
vba
1 --セット条件に当てはまる引数をSetCellに渡す。 2 --pRow = 対象行数 3 --pClumn = 対象列数 4 --pDuaringPattern = 期間パターン 5 --pProgressSituation = 進捗状況 6 Sub SetCells(pClumn As Integer) 7 8 For pRow = 6 To rowsCount 9 10 --対象セルのデータを格納する。 11 pCellDate = Cells(pRow, pClumn).Value 12 --対象セルのデータの存在チェック 13 If Cells(pRow, pClumn).Value = "" Then 14 Exit For 15 End If 16 17 --期間パターンを格納する変数。 18 Dim pDuringPattern As Integer 19 --期間パターンセット 20 If pCellDate < cellDateFrom Then 21 pDuringPattern = 0 22 ElseIf pCellDate = cellDateFrom Then 23 pDuringPattern = 1 24 ElseIf cellDateFrom < pCellDate And pCellDate < cellDateTo Then 25 pDuringPattern = 2 26 ElseIf pCellDate = cellDateTo Then 27 pDuringPattern = 3 28 ElseIf cellDateTo < pCellDate Then 29 pDuringPattern = 4 30 End If 31 32 --進捗状況を格納する変数 33 Dim pProgressSituation As Integer 34 --進捗状況セット 35 cellDataD = Cells(pRow, 4).Value 36 Select Case cellDataD 37 Case 100 38 pProgressSituation = 0 39 Case 0 40 pProgressSituation = 1 41 Case 1 To 99 42 pProgressSituation = 2 43 End Select 44 45 --セルに文字をセットする処理 46 Call SetCell(pRow, pClumn, pDuringPattern, pProgressSituation) 47 48 Next pRow 49 50 End Sub 51 52 53 --対象セルへの文字列セット処理。 54 --pString = セットする文字列 55 --pClumn = 2:着手状態 3:完了状況 56 --pProgressSituation = 0:進捗状況100% 1:進捗状況0% 2:進捗状況1~99% 57 --pDuringPattern = 期間のパターン 4:報告期間未満 58 Sub SetCell(pRow As Variant, pClumn As Integer, pDuringPattern As Integer, pProgressSituation As Integer) 59 60 --対象セルにセットする文字を格納する変数 61 Dim pString As String 62 63 If pClumn = 2 Then 64 If pDuringPattern = 4 Then 65 Select Case pProgressSituation 66 Case 0, 2 67 pString = C_START_FIRST 68 Case 1 69 pString = C_START_EMP 70 End Select 71 Else 72 Select Case pProgressSituation 73 Case 0, 2 74 pString = C_START 75 Case 1 76 pString = C_START_LATE 77 End Select 78 End If 79 Else 80 If pDuringPattern = 4 Then 81 Select Case pProgressSituation 82 Case 0 83 pString = C_END_FIRST 84 Case 1, 2 85 pString = C_END_EMP 86 End Select 87 Else 88 Select Case pProgressSituation 89 Case 0 90 pString = C_END 91 Case 1, 2 92 pString = C_END_LATE 93 End Select 94 End If 95 End If 96 97 --対象セルへの文字セット 98 Cells(pRow, pClumn + 3).Value = pString 99 End Sub 100
回答5件
あなたの回答
tips
プレビュー