• ベストアンサー

割り算のあまり

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

専門家に質問してみよう