質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

2853閲覧

コードが全然短くなりません。アドバイスお願いします。

King_of_Flies

総合スコア382

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2017/09/27 08:12

編集2017/09/28 02:29

VBAのツールで下記メソッドを実装しました。

パターンごとにIf分岐しているのですが、
さすがに長いと思わざるを得ません。

withを使用しようかとも考えましたが、
見ずらくなりましたので、戻しました。
cellDateFromは報告期間FROM
cellDateToには報告期間TO
cellDateBには作業着手予定日
cellDateCには作業完了予定日
でそれぞれDate型です。

cellDateDにはInteger型で進捗度が入っています。

Ifの分岐を短くすることは可能でしょうか。。

ozwkさんの回答を参考に修正した後のコードです。

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 cellDateD = Cells(i, 4).Value 13 '① 14 If cellDateC < cellDateFrom Then 15 Call Selecter(i, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, 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, cellDateD, C_START, C_END, C_START, C_END_LATE, C_START_LATE, C_END_LATE) 58 End If 59 Next i 60 End Sub 61'メソッド名は後で考えます。 62Sub Selecter(count As Variant, cellDateD As Integer, str1 As String, str2 As String, str3 As String, str4 As String, str5 As String, str6 As String) 63 Select Case cellDateD 64 Case 100 65 Cells(count, 5).Value = str1 66 Cells(count, 6).Value = str2 67 Case 1 To 99 68 Cells(count, 5).Value = str3 69 Cells(count, 6).Value = str4 70 Case 0 71 Cells(count, 5).Value = str5 72 Cells(count, 6).Value = str6 73 End Select 74 End Sub

追記
どうしてこのような分岐パターンができたのかという画像があったのですが、
イメージの追加ができませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momon-ga

2017/09/27 09:19

ifの分岐を短くしたいののイメージを補足して下さい。16パターンあれば分岐は16になるのでは?短くしたいのはifの中のcaseの書き方?
King_of_Flies

2017/09/28 02:25

分岐パターンは15個あります。短くしたいのはIf分の中で、ozwkさんの回答からプログラムを修正し、Select Caseの記述を切り出して、If分の中身は短くすることが出ました。なのでそのプログラムを質問で編集しています。
King_of_Flies

2017/09/28 02:26

ただ、その修正後のプログラムを見てわかると思いますが、分岐パターン15のうち、同じ結果をセットする処理がいくつかあり、これを短くするにはどうすればよいかというとことで、悩んでいます。
King_of_Flies

2017/09/28 03:11

カルーノ図とやらがもしかしたらコードを短くするヒントになるかもしれないですね。少し調べてみます。
guest

回答2

0

要件わかってないですが、結果表を作成して、インデックスの取得を関数化すればよいかと。
変数名が全然いけてないので修正ですね。

VBA

1Sub CellSetter() 2 3 Dim RESULT(1, 2) 'パターン数 × cellDateDの分岐数 4 'めんどいのでコピペですが・・・ 5 RESULT(0, 0) = Array(C_START_EMP, C_END) 6 RESULT(0, 1) = Array(C_START, C_LATE) 7 RESULT(0, 2) = Array(C_START_TMP, C_END) 8 RESULT(1, 0) = Array(C_START_EMP, C_END) 9 RESULT(1, 1) = Array(C_START_EMP, C_END) 10 RESULT(1, 2) = Array(C_START_EMP, C_END) 11'ここまで、初期設定 12 13 For i = 6 To rowsCount 14 hyo_PT = getPT(cellDateB, cellDateC, cellDateFrom, cellDateTo) 15 hyo_POS = getPos(cellDateD) 16 17 Cells(i, 5).Value = RESULT(hyo_PT, hyo_POS)(0) 18 Cells(i, 6).Value = RESULT(hyo_PT, hyo_POS)(1) 19 Next 20 21End Sub 22 23Function getPos(cellDateD) 24 Select Case cellDateD 25 Case 100 26 getPos = 2 27 Case 1 To 99 28 getPos = 1 29 Case 0 30 getPos = 0 31 End Select 32End Function 33 34Function getPT(cellDateB, cellDateC, cellDateFrom, cellDateTo) 35'面倒なので実装は書かないですが、意味は伝わるかと・・・ 36 getPT = 0 '例の日付の大小のif文 37End Function

投稿2017/09/27 10:17

momon-ga

総合スコア4820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

King_of_Flies

2017/09/28 02:35

一番最初の初期設定のコメントでパターン数*CellDateDの分岐数の宣言をするとのことですが、 こうなると45パターン書くことになりますね。 これはちょっと厳しいかもしれないです。 ただ、GetPosとGetPTの考え方は参考になるものがありました。 このあたりを自分で考えて組み込んでみるのもありですね! しばらくお待ちを。
guest

0

ベストアンサー

長いので全然内容読んでませんが、

VBA

1(Else)If 条件式 Then 2 Select Case cellDateD 3 Case 100 4 Cells(i, 5).Value = 値A 5 Cells(i, 6).Value = 値B 6 Case 1 To 99 7 Cells(i, 5).Value = 値C 8 Cells(i, 6).Value = 値D 9 Case 0 10 Cells(i, 5).Value = 値E 11 Cells(i, 6).Value = 値F 12 End Select 13...

というパターンの繰り返しなので
Select部分をf(i,値A,値B,...,値F)と置けば
単純に

VBA

1(Else)If 条件式 Then 2 f(i,値A,値B, ... ,値F) 3(Else)If 条件式 Then 4 f(i,値A,値B, ... ,値F) 5(Else)If 条件式 Then 6 f(i,値A,値B, ... ,値F) 7(Else)If 条件式 Then 8 f(i,値A,値B, ... ,値F) 9...

で、これで少し見やすくなると、
条件式が違うだけでやっていることが同じなところが何箇所も見つかると思います。
それら条件式を論理的にまとめると更に減ります。

例えば3,4は
3:(B < F And F < C And C < T )
4:(F = B And F < C And C < T )
なので
(B <= F And F < C And C < T )にまとまります

投稿2017/09/27 08:24

編集2017/09/28 02:59
ozwk

総合スコア13528

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問