• ベストアンサー

割り算のあまり

ExcelのVBAを独学しています。 入門書にカレンダーを作るプログラムがありました。 横1列が日曜から始まり土曜で終わる1週間でその列が終わると次の行に移るプログラムが次の部分です。 このなかで(CellRetsu - 1)の部分が理解できません。 たしかにー1ととると金曜で下の行に移ってしまうのでー1が必要なのです。 しかし、普通に考えると土曜までで7列なので-1がいらないと思ってしまうのですが。 どなたか説明していただけるととても助かります。 よろしくお願いいたします。 If ((CellRetsu - 1) Mod 7) = 0 Then ' セルの(列-1)を7で割って ' 余りがなければ… CellRetsu = 1 ' CellRetsuをA列に CellGyo = CellGyo + 1 ' 行を1つ進めて翌週に End If

質問者が選んだベストアンサー

  • ベストアンサー
  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.1

要するに1列目をあまり0とするために1だけ差が出るのです。 さらに言うと8日目が初めて2行目にいくためにも 7日目は1行目に居てもらわないと困るのです。 つまり1を引いておかないといけないのです。 あまり(MOD)を使う計算は大抵0基準ですのでよく慣れておいてください。

sakura54
質問者

お礼

ymmasayan様 >あまり(MOD)を使う計算は大抵0基準 このような基本的なことも知りませんでした。 貴重なご助言ありがとうございました。

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

こんばんは。 ご質問とは離れますが、 >著作権に触れるのではないかと気になりつい直接関係する部分だけをコピーしてしまいました。 一般的な引用のルールは、どこから引用したのかを書いて、あくまでも、自分の書いている内容が主になっていれば、ほぼ問題はありません。今回はアルゴリズムではありませんが、最初から、アルゴリズムには著作権がありません。 それと、基本的には、Office VBAコードには、著作権がないと思っていたほうが無難です。だから、著作権を主張したい場合は、コードは公開しないことです。 ここのサイトの著作権については、一般的なルールとは違い、著作権については甘めになっています。ですから、中には、丸写しのような、ひどい内容もあります。 それから、話が戻りますが、Mod演算子は、ワークシートのMOD関数とは基本的には違いますから、気をつけてくださいね。とても間違いやすいです。 '------------------------ Dim a As Double Dim b As Double Dim c As Variant a = 10.1 b = 1   c = a Mod b 'cは、Double 型にはならない。 '------------------------ ワークシート関数 =MOD(10.1,1)

sakura54
質問者

お礼

Wendy02様 再び貴重なご助言を感謝いたします。 >基本的には、Office VBAコードには、著作権がないと思っていたほうが無難です このような知識があれば、最初からコードをすべてコピーして(出典を明らかにしたうえで)ご助言頂けたのにと残念です。 >Mod演算子は、ワークシートのMOD関数とは基本的には違いますから これも初めて知り、ためしてみたら、戻り値の符号が逆になるので違うものだということはわかりました。 いろいろ教えていただいてありがとうございました。

回答No.5

回答4です。また補足です。 私が言いたかったことはコードの可読性です。動作上は問題なくても、プログラムのメンテナンスに大きく係わります。たとえば Dim x As Integer x=1 Mod 10 などと書かれていたら、どうでしょう?これは「X=1」と同値ですが、単に「X=1」と書くのとは別の意味があるのではないか、という疑問を持ちませんか? このように、ひとつのコードにいくつかの意味が紛れ込むような書き方は、メンテナンス上好ましくありません。後々になって別のプログラマが修正する時に、判断に困ったり、誤解に基づいて修正しかねないからです。 今回の場合、「(CellRetsu - 1) Mod 7」がとりうる値と変数「CellRetsu」がとりうる値はほぼ同じです。「If CellRetsu = 8 Then」で十分であって、わざわざ「If ((CellRetsu - 1) Mod 7) = 0 Then 」と書く利点や必要性がありません。 文法上、動作上は問題なくても、実行コストとメンテナンスコストを押し上げる書き方なので「不適切」といえると思います。

回答No.4

回答2です。補足と訂正です。 >曜日によって列が移動するのなら、普通は >>If ((CellRetsu - 1) Mod 7) = 0 Then ' >ではなく >If (Weekday(<日付>) Mod 7)=0 Then Mod関数は、増加し続ける数値に対して使うものです。 ですから、1-7(8?)の範囲で増減を繰り返す変数に対してModを使う必要はありません。 Modを使うとその変数が8以上になると誤解を与えかねないので、むしろ使わない方がいいでしょう。 その理由で私の >If (Weekday(<日付>) Mod 7)=0 Then も不適切でした。

sakura54
質問者

お礼

cistronezk様 補足と訂正まで頂いて感謝しております。 >Mod関数は、増加し続ける数値に対して使うものです。 Mod関数については割り算の余りを返すことしか知りませんでしたのでもう少し調べてみたいと思います。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 質問のポイントだけでは、回答者はまごついてしまいます。ある意味では、回答者を試しているのと同じことだと思います。内容としては、まるで詰め将棋みたいなものです。ある程度のVBAのレベルの人には、それなりに自分のコードのパターンを持っているので、そのパターンを捨てないといけなくなります。 独学の教本としては、そういう個人の癖のようなパターンを学ぶのは、あまり関心しませんね。以下のコードは、可もなく不可もなくというところです。 >このなかで(CellRetsu - 1)の部分が理解できません。 > If (CellRetsu - 1) Mod 7 = 0 Then 別に、 If CellRetsu Mod 7 = 1 Then でも可能です。 こういうのは、個人のパターンの範疇です。別に0であろうが、1であろうが、数値を書く以上は、どちらでも良いことです。一般的な決まりはありませんが、右辺を0 にするために、括弧を増やしているのなら、あまり関心しません。 >横1列が日曜から始まり土曜で終わる1週間でその列が終わると次の行に移るプログラムが次の部分です。 コードをみる限りは、単に列の数だけで、土曜日で次の行に移るという意味ではありません。 その変数から想像したコード。 '------------------------------------------- Sub CalendarMaking()   Dim myDate As Date   Dim LastDate As Date   Dim i As Integer   Dim CellGyo As Integer   Dim CellRetsu As Integer      '-------------------------------------------   '曜日の作成   Range("A1").CurrentRegion.ClearContents   For i = 1 To 7     Cells(1, i).Value = Format(i, "aaa")   Next i   '-------------------------------------------   '日付を入れる   myDate = DateSerial(2009, 9, 1)   LastDate = DateSerial(Year(myDate), Month(myDate) + 1, 0)      CellGyo = 2 '最初の行   CellRetsu = Weekday(myDate) '1日の列数      For i = 1 To Day(LastDate)          If (CellRetsu - 1) Mod 7 = 0 Then '*       CellRetsu = 1       CellGyo = CellGyo + 1     End If     Cells(CellGyo, CellRetsu).Value = i          CellRetsu = CellRetsu + 1   Next i End Sub

sakura54
質問者

お礼

wendy02様 >質問のポイントだけでは、回答者はまごついてしまいます 本当に失礼いたしました。 私も、全コードを見ていただかないと不都合があるのではないかと思ったのですが、著作権に触れるのではないかと気になりつい直接関係する部分だけをコピーしてしまいました。 このようなコード例まで親切に書いていただき感激しております。 勉強させていただきます。

回答No.2

質問文だけでは「CellRetsu」の初期値とその後の増減の仕方が不明です。 曜日とCellRetsuが連動していると思いますが、それはどうなっていますか? 曜日によって列が移動するのなら、普通は >If ((CellRetsu - 1) Mod 7) = 0 Then ' ではなく If (Weekday(<日付>) Mod 7)=0 Then とかにすると思うのですが、他の部分はどうなっているんでしょうか? ちなみに、示されたコードから判断すると >If ((CellRetsu - 1) Mod 7) = 0 Then ' とする必要はなく、単に If CellRetsu = 8 Then でいいような気もします。

関連するQ&A

  • Mod関数?に関して

    会社のASPのソースの中に以下のようなものがあります。 <% for iRowAnswer = 0 to ubound(ArrAnswer, 2)   if iRowAnswer Mod 4 = 0 And iRowAnswer > 0 then ・・・・・ とあるのですが、2行目のif文のModはどのように解釈すればよろしいのでしょうか? Modというと N = MOD(30,4) という感じで割り算の余りを計算する関数という認識しかないのですが、まったく違う使い方なのでしょうか? これだけでは分からないかも知れないのですが、どうぞよろしくお願い致します。

  • マクロで当番表

    Excelマクロで当番表を作成しているのですが、わからない事があるのでお教えください。 例えば1週間毎にAさん、Bさん、Cさん、Dさん4人を振り分けたいのですが、分岐、判断方法がわかりません。 1年間のカレンダーは出来上がっています。 当方の企業は完全週休2日で祝祭日も休みです。カレンダーの休日にはセルを塗りつぶしています。(マクロで34の薄い水色です。) そこで、休日セルの塗りつぶしを背景で、日曜日~土曜日までを曜日で情報を受け取り作成したいのですが、うまくいきません。 月曜から金曜までをAさん、次の週の月曜から金曜までをBさんにしたいのです。 また、Dさんが終わればAさんに戻る。 下記は曜日と背景の例です。 if then ElseでもDo until loopでも他の方法でもよろしいのでお教えください。 曜日=Right(Sheets("カレンダー").Cells(行, 列).Value, 1) 背景 = Cells(行, 曜日列).Interior.ColorIndex

  • VBAで処理フラグの立て方

    こういった条件でやりたいのですがうまくいきません・・・ 処理フラグの立て方は間違っていないと思うのですが・・・ ちょっとセルとかは変えてあります。 もしE3の値が4で割り切れたら8行目を削除し次の処理は行わない もしE3の値が4で割り切れなかったらE4の値が4で割り切れるか処理をする。 割り切れたら18行目を削除 E3とE4の値両方が4で割り切れなかったら8行目を削除し1行あがるので17行目を削除したいです Sub rdlt() If Range("I1").Value = 0 Then Range("I1").Value = 1 '処理は一度きり If Range("E3").Value Mod 4 = 0 Then Rows("8:8").delete '4で割れたとき8行目を削除 Range("J1").Value = 1 '4で割れたときは次の処理用にフラグ End If If Range("J1").Value = 0 Then 'E3が4で割れなかったときは処理する If Range("E4").Value Mod 4 <> 0 Then Rows("18:18").delete Range("J1").Value = 1 End If End If End If End Sub

  • エクセルVBAについて

    いつもお世話になっています。 VBAで、「B列(曜日の列・カレンダーは自動作成されます)が”金曜”だったら、その隣のC列に”●●”と入力する」というプログラムを作りたいと思っています。 今のところ 'B列の曜日が金曜日だったらC列に●●をセットする Set TargetRange = Range("B5:B35") For Each B In TargetRange If B.Value = "金" Then Cells(C.Cell).Value = "●●" End If Next となっていて、コンパイルは通るんですが実行されません。 番地を指定するのかな?とか予想はしているのですが・・・。 ヒントなどでも結構なので、ご教授ください。 お願い致します。

  • 行ごとに判定するマクロについて教えて下さい

    行ごとに判定するマクロについて教えて下さい。 下記のようなマクロで、添付ファイルのように、行ごとで E列からN列で違った数値がないか、入力されていないセルがないかを調べ 4つすべてのセルが同じ数値でない場合は塗りつぶしはされず O列にOKを表示しないようなマクロを組みたいのですが 現在のマクロだと、行ごとではなく、E3~N102セルまでの中で 同じ数値がないかを判断してしまっているため K11セルやK15セルのように数値が入力されていないにも関わらずO列の部分にOKが出てしまいます。 他の行に同じ数値が入っているのは関係なしにして 11行目なら11行目だけで 15行目なら15行目だけで、というように行ごに判定していくには どのようにすればいいでしょうか? Sub 判定マクロ回転() Dim i As Integer, j As Integer Range(Cells(3, 15), Cells(102, 15)).ClearContents For i = 3 To 102 For j = 5 To 14 Cells(i, j).Interior.ColorIndex = 0 If WorksheetFunction.CountIf(Range("E3:N102"), Cells(i, j)) > 3 Then If Cells(i, j).Row Mod 2 = 1 Then Cells(i, j).Interior.ColorIndex = 6 Cells(i, 15) = "OK" Else If Cells(i, j).Row Mod 2 = 0 Then Cells(i, j).Interior.ColorIndex = 40 Cells(i, 15) = "OK" End If End If End If Next j Next i If WorksheetFunction.CountIf(Range("O3:O102"), "OK") > 99 Then MsgBox "データチェックOK(^O^)b" End If End Sub

  • =MOD(ROW(),2)=0が一行置きになる意味

    初歩的な質問ですみません。 =MOD(ROW(),2)=0 について教えてください。 MODはあまりを返す関数、ROWが行を示す関数ということはわかるのですが、どうしてこの「=MOD(ROW(),2)=0」という数式が「一行置きに」を表すようになるのでしょうか? 「ROWの()で指定した範囲の行番号を2で割ったときの余りが0」ということだと思うのですが、これは「余りが0=偶数」だから「偶数行を指定する=一行置き」という理解であっていますか? また、( )の中を「,」で区切るのはどういう意味を持ちますか? 関数によって違うとも思いますが、「,」の前と後で、「前の数値に(を)後の数値を(で)」というかんじでしょうか?「IF」関数の場合「,」がいくつも続く時はどういう意味になりますか?

  • エクセルVBAについての質問です。

    エクセルVBAについての質問です。 A列のCという商品名が入った列を削除したい場合下記のようにすれば可能かと思いますが、C列のCという商品名が入った列を削除したい場合どのようにすればよいか教えて下さい。 VBAに関してまだ初心者ですがどうぞよろしくお願いします。 行 = 1 Do 行 = 行 + 1 If Cells(行, 1) = "" Then Exit Do End If '行の値がC以外の時は次の行に移る Do If Cells(行, 1) = "C" Then Rows(行 & ":" & 行).Select Selection.Delete Shift:=xlUp Else Exit Do 'ジャンプ先は内側のDo~Loopのすぐ下 End If Loop 'ジャンプ先はここ If Cells(行, 1) = "" Then Exit Do End If Loop End Sub

  • エクセルで年月日の週を求める関数を教えてください

    例えば2006年4月7日は第一金曜という風に。 カレンダー上では第二週ですが、其の月々の何回目の週になるかを計算する関数を教えてください。 エクセルの列には4月も5月もすべて縦に日付を入力して次の列のセルに週が表示できればと思います。 つまり、countif関数以外がいいかと思います。 すみませんが、ご回答よろしくお願いします。 WEELNUMとかMODが使えそうかとおもいますが、うまく考えられません。

  • VBAカレンダーから予定をmsgboxに表示

    If Application.CountIf(seets("seet3").Range("i5:i500"), C.Value) > 0 Then 構文の先頭がこれでよいのかも分かりません。教えてください、、、 ("sheet3")のi列5行目から500行まで予定日付、j列5行目から500行まで予定詳細が入力されています。("sheet2")にカレンダーがあり初期化して年/月を呼び出すとその月の予定日と予定詳細がmsgBoxに表示されるようにしたいのです。宜しくお願いします。

  • ユーザー定義関数でA列の値に応じてB列の値を変える

       A列      B列 1行   Type   名称 2行     1    あ 3行    2    い 4行    3    う VBA初心者のものです。ユーザー定義関数を作成して、A列のTypeの値に応じて、B列の名称の値を変化させる式を作成中です。B列2行目に、下記のユーザー関数をセル式として記述し、3・4行目にコピーしたのですが、0が表示されてしまいます。 どうしてでしょうか? Functionめいしょう(Type, 名称) Sheets("突合せ").Select If  Type = 1 Then 名称 ="あ" Exit Function     If  Type = 2 Then   名称 = "い"   Exit Function        If  Type = 3 Then        名称 = "う"           Exit Function       End If     End If End If End Function

専門家に質問してみよう