[[20141024002243]] 『マクロで合計 3』(もみじ坂) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『マクロで合計 3』(もみじ坂)

[[20140814193616]]『マクロで合計 1』
[[20140827212357]]『マクロで合計 2』

 ◎ HANA様 レッスン用

 ◆今回の課題
  1. 使用していない空欄の行を非表示する方法&その他もろもろ
  2.エラーの処理。
  「今のコードのままではMatch関数で検索値が無かった時にエラーになって止まります。
   変数の型をLongで行くのなら、
   データー.Cells(i, "E") の値が 集計.Range("A:A") の範囲に有るかどうか
   COUNTIF関数等で調べてからMatch関数が行われる様にしておくのが良いと思います。
   また、検索値が無かった場合にどうするのかも決めておいてもらえると良いと思います。
   無かったものは集計しないのか
   処理を中断して、追加してもらって もう一度実行してもらうのか」

 ●データーシート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[g]	[h]
[1]	書類NO	日付	TEL	月検索値	NO	NO検索値		単価	cs	pc
[2]	140124 	2014年1月5日	8768 		A01					10 
[3]	140124 	2014年1月5日	8768 		A01					20 
[4]	140124 	2014年1月5日	8768 		A03					30 
[5]	140124 	2014年1月5日	8768 		A04					40 
[6]	140124 	2014年3月5日	8768 		A03					50 
[7]	140124 	2014年3月5日	8768 		A05					60 
[8]	140124 	2014年3月5日	8768 		A05					70 

 ●集計シート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]		8768							
[2]	NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
[3]	A01				     30 				30 
[4]	A02								
[5]	A03				     30 		50 		80 
[6]	A04				     40 				40 
[7]	A05						    130 		130 
[8]	A06

 ●コード

 Sub test8()
    Dim NO検索, NO最終行 As Long
    Dim 月検索, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")
    NO最終行 = 集計.Range("A3").End(xlDown).Row
    月最終列 = 集計.Range("E2").End(xlToRight).Column

    '行を再表示させる
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
           月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

              If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")
                 End If
              End If
      Next i

    '空欄の行を非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub

< 使用 Excel:Excel2010、使用 OS:Windows7 >

 ※HELP機能は付いていない機種です。

 >コードの中に 月とNOを2か所使用しているんですが、
 >For 〜 Next の中に設定している 月とNO は
 >For 〜 Next のループ内のみ使用することができるんですよね

 変数はどこにおいても使用できるんですね。
 For 〜 Nextの内外とわずに

 今回疑問になったきっかけは、
 コードを見てるうちにどこの月&NO 使っているのかが分からなくなったからです (*゚ ゚;*)

 HANA様が指摘したとおりに変数をそれぞれ違う名前に変更後、
 改めて自分の認識違いにビックリしました。

 説明文を読まなければきっとこう思ってました。
 If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO最終行, 月最終列) = 集計.Cells(NO最終行, 月最終列) + データー.Cells(i, "j")
                 End If
              End If

 結果は散々でしたが (゚д゚lll)!

 気づいてよかったです。

 ところで、携帯からでは見づらくはないですか?PC使える環境になるのはどれぐらいの期間になりそうですか?
(もみじ坂) 2014/10/24(金) 00:36

 お待たせしました。
 今日中には、PC生活に戻れます。

 変数のツカイドコロ、わかっていただけましたか?
 同じ「調べた結果の情報」を使いたい様な場合に
 変数にメモしておくと、次にそのメモを見れば良いので
 再度調べなくて良いのです。

 たとえば、この部分
NO最終行 = 集計.Range("A3").End(xlDown).Row
 の =以降と
For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
 の To以降は良く似ていますが
 片方は、変数に入れるだけで
   実際の使用はもうすこし下の行です。
 片方は、求めた値を直接使っていますね。

 似たようなものが違う書き方がしてあるのに、私が文句を言わないのは
 1.後で使いたい値か
 2.使いたい所に直接書いた場合、可読性はどうか
 と言った点で違いがあるからです。

 ちなみに、最終行を
     .End(xlDown)
     .End(xlUp)
 の二つの書き方で求めて居るのは
 その内指摘しようと思ってました。

 (HANA)

 >.End(xlDown)
 >.End(xlUp)

 二つを使ったのは

 欲しい結果を得るためにそうする必要があるからです。

 データーシート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[g]	[h]
[1]	書類NO	日付	TEL	月検索値	NO	NO検索値		単価	cs	pc
[2]	140124 	2014年1月5日	8768 		A01					10 
[3]	140124 	2014年1月5日	8768 		A01					20 
[4]	140124 	2014年1月5日	8768 		A03					30 
[5]	140124 	2014年1月5日	8768 		A04					40 
[6]	140124 	2014年3月5日	8768 		A03					50 
[7]	140124 	2014年3月5日	8768 		A05					60 
[8]	140124 	2014年3月5日	8768 		A05					70 

 NO最終行 = 集計.Range("A3").End(xlUp).Row
 を使用した場合結果が下記になります
 コードを一回目実行するときはは下記に結果になります。
 コードを2回目実行するとき「400」のエラーメッセージが出るんです。
 原因はE1〜I3の値が消されたからです。

 集計シート
 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]		8768							
[2]	NO	商品名前	個数	名称					
[3]	A01								
[4]	A02								
[5]	A03				    30 		50 		80
[6]	A04				    40 				40
[7]	A05						    130 		130
[8]	A06								

 NO最終行 = 集計.Range("A3").End(xlDown).Row
 を使用した場合は欲しい結果を得ることができましたので、
 こちらを使いました。

 集計シート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]		8768							
[2]	NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
[3]	A01				     30 				30 
[4]	A02								
[5]	A03				     30 		50 		80 
[6]	A04				     40 				40 
[7]	A05						    130 		130 
[8]	A06								

(もみじ坂) 2014/10/24(金) 20:04


 >変数のツカイドコロ、わかっていただけましたか?
 はい、だいたいわかりました。

 >と言った点で違いがあるからです。
 そうだったんですか?

 とりあえず必要なものを追加してその形になったかんじです。
 あまり気にしていませんでした ΣΣ(゚д゚lll)!

(もみじ坂) 2014/10/24(金) 20:25


 End(xlUp) と End(xlDown) の違いが分かりますか?

 たとえば、A3セルをアクティブにして Ctrl+↑ でアクティブになるセルと
      A3セルをアクティブにして Ctrl+↓ でアクティブになるセルは
 違いますよね?

 End(xlUp)が、Ctrl+↑
 End(xlDown)が、Ctrl+↓ です。

 データー.Cells(Rows.Count, 1).End(xlUp).Row
 の時の、基準になるセル
  (このコードをワークシート上で確認しようと思った時に最初にアクティブにするセル)
 が、どのセルかわかりますか?

 ちなみに
 集計.Range("A3").End(xlUp).Row
 だと、A3セルと言う事ですが。
  
(HANA) 2014/10/24(金) 22:49

 >End(xlUp) と End(xlDown) の違いが分かりますか?

 はい、以前教えていただきました (*´-`*)ゞ ポリポリ

 なので、NO最終行 = 集計.Range("A3").End(xlDown).Row
 を使用したのです。

 >集計.Range("A3").End(xlUp).Row
 A3から Ctrl+↑ 最後の行を読み取るんですよね

(もみじ坂) 2014/10/25(土) 00:37


 もみじ坂さんの説明が、どうしても
  こうやって見たらうまく行ったから、こうやるしかない!!
 と言っておられるように感じるんですよね。

 そうじゃないのを確認したいので
 End(xlUp).Rowを使って書き直してみてもらえますか?

 A地点からC地点に行く方法として
 A地点→B地点→C地点と進むルートと
 A地点→D地点→C地点と進むルートがあった時
 出来れば、両方のルートをわかっていた方が良いと思います。

 A地点→B地点→C地点と進むルート が「End(xlDown)」を使った方法とします。
 コードを実行すると 変数:NO最終行 に 目的の値=8 が得られます。

 では、A地点→D地点→C地点と進むルートを「End(xlDown)」と考えて
 実行すると 変数:NO最終行 に 目的の値=8 が得られるコードを作ってみて下さい。
    
(HANA) 2014/10/25(土) 08:08

 >こうやって見たらうまく行ったから、こうやるしかない!!

  といいますか。回答が複数がある時はその癖が出ますね (゚д゚lll)!
  回答が1個の場合はとことんと原因究明するしかないので、それは出ないようです。

 癖というのはなかなか意識しないとなかなか治らないものですね (*´ノД`)

 ちょっとわかりやすいように番号を全部振ってみました。

 	[a]	 [b]	    [c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]									
[2]	NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
[3]	3	  3	     3	3	3	3	3	3	3
[4]	4	  4	     4	4	4	4	4	4	4
[5]	5	  5	     5	5	5	5	5	5	5
[6]	6	  6	     6	6	6	6	6	6	6
[7]	7	  7	     7	7	7	7	7	7	7
[8]	8	  8	     8	8	8	8	8	8	8

 ◆A地点→B地点→C地点と進むルート → 「End(xlDown)」= 「変数:NO最終行 に 目的の値=8」

 NO最終行 = 集計.Range("A3").End(xlDown).Row
 月最終列 = 集計.Range("E2").End(xlToRight).Column

 の場合は  A3 → A8 → K8 = 取得範囲 A3:K8

 ◆A地点→D地点→C地点と進むルート → 「End(xlUp)」 = 「変数:NO最終行 に 目的の値=8」

 ※私が間違えたやつ
 NO最終行 = 集計.Range("A3").End(xlUp).Row
 月最終列 = 集計.Range("E2").End(xlToRight).Column

 A3 → A1 → K3  = 取得範囲 A1:K3  多分こんな感じだと思います。

 ※正しいのEnd(xlUp).Row使い方
 NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
 月最終列 = 集計.Range("E2").End(xlToRight).Column

 A1048576(エクセルの最終行) → A8 → K8  = 取得範囲 A8:K3

 回答はこんな感じですがあってますか?
 NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row 
 のみですと 始点と終点しかないので、 最終列も入れましたが。。。。

 
(もみじ坂) 2014/10/27(月) 19:02


 NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row 
 そうですね。

 最終行より下のセルから Ctrl+↑ で探さなと
 最終行のセルは見つかりません。

 月最終列も、End(xlToRight)で探していますが、End(xlToLeft)ってのも存在します。
 せっかくなので、こちらも試してみられてはどうでしょう。

 ちなみに、Range(○○) の「○○」は文字列でセル番地を入れますよね。「""」でくくってあるので。
 なので 集計.Range("A" & Rows.Count).End(xlUp).Row こんな書き方も出来ます。

 同じコード内で、同じ様な事をする場合は
 なるべく同じ様な構造にしておくのが良いと思います。

 NO最終行 を取得するときも、ループの終わりを取得するときも
 「データの最終行を特定する」と言う同じ言葉で求められる値ですよね。
  
(HANA) 2014/10/27(月) 22:04

 >集計.Range("A" & Rows.Count).End(xlUp).Row
 Range で書くと こんなくくり方だったんですね _〆(・v・★)

 でもなんでだろう (??)
 Cells を 使う方が 親しみを感じるのは 私だけでしょうか?

 NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
  → 集計.Range("A" & Rows.Count).End(xlUp).Row
 月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column
 →これですと Range への変換は可能でしょうか? 私には Cellsしか思いつかないです (*´ノД`)

 ◆結果

 エクセルの最終列 → K3 → A8 = 取得範囲 A8:K2

 >「データの最終行を特定する」と言う同じ言葉で求められる値ですよね。
 はいそうですね

(もみじ坂) 2014/10/28(火) 23:33


 >Cells を 使う方が 親しみを感じるのは 私だけでしょうか?
 どうですかね。
 私は Rangeを使ってある方が見やすいですが。。。
 好き好きだと思います。

 >月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column
 > →これですと Range への変換は可能でしょうか? 私には Cellsしか思いつかないです (*´ノД`)
 こんな時は、Cellsを使う方がスマートだと思いますし。

 >>「データの最終行を特定する」と言う同じ言葉で求められる値ですよね。
 >はいそうですね 
 だから、同じ書き方が出来ない時に「なんで同じ書き方が出来ないんだろう?」と
 突き詰めてもらえたら良かったと思います。

 じゃあ、次に 値が無かった時にエラーになる件ですね。

 変数の型が。。。。。いま
    Dim NO検索, NO最終行 As Long
 って書いてありますね。

 これだと、NO検索の型は指定していない=Variant になってしまいます。
    Dim NO検索 As Variant, NO最終行 As Long
 と書いてあるのと同じ。

 当初通り、Longで指定した場合 変数:NO検索 には値しか入りません。
 値以外を入れようとしたら、その時点でエラーになります。

 つまり
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 この行でエラーにならなければ、変数:NO検索 には値が入っているのです。

 すると
              If IsNumeric(NO検索) Then
 この行は必ず TRUE です。

 もう一度変数の型を何にするのかよく考えてみて下さい。

 Variantにして、エラー値でもなんでも入る様にして 結果が値だったかどうか確認して処理をするのか
 Longにして、エラーにならない事を確認して 結果を変数に入れるのか。
  
(HANA) 2014/10/29(水) 08:50

 > 突き詰めてもらえたら良かったと思います。
 やってみましたよ 〜 ( ;∀;)
 調べ見ましたよ〜 "(-""-)"
 でも見つからなかったです。。。。。
 .Rangeは列はかけても 行は 書けなかったんですよ。。。

 ◆じゃあ、次に 値が無かった時にエラーになる件ですね。

 Dim NO検索, NO最終行 As Long = Dim NO検索 As Variant, NO最終行 As Long
 になるんですか?
 Dim NO検索, NO最終行 As Long = Dim NO検索 ・NO最終行 As Long
 と勘違いてました ( ゚Д゚)

 ◆Long にする場合は エラーにならない事を確認して 結果を変数に入れないといけない。

 Dim NO検索 As Long
 Dim NO最終行 As Long  が正しいのですね

 ここも私の認識間違いかもです。

 If IsNumeric(NO検索) Then は
 TRUE の もののみを拾ってくれ という 指令文と思ってました。
 flash(集計シートにあって、データーシートにない場合)
 の 場合は拾わない = 無視する ものではないのですね

 Variantを使用の時は
 Dim NO検索 ,NO最終行 であれば OK?

 ただし、値がないとき以外のエラーもスルーされるであってますか?

(もみじ坂) 2014/10/30(木) 14:24


 > .Rangeは列はかけても 行は 書けなかったんですよ。。。
 いや、そこじゃなくて
    NO最終行 = 集計.Range("A3").End(xlDown).Row
    For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
 の事です。

 >Dim NO検索 As Long
 >Dim NO最終行 As Long  が正しいのですね
 一行で書いても良いですが
  Dim NO検索 As Long, NO最終行 As Long
 一つずつに対して、型を書く必要があります。

 >If IsNumeric(NO検索) Then は
 >TRUE の もののみを拾ってくれ という 指令文と思ってました。 
 そうですね。違いますね。

 ワークシート関数に ISNUMBER が有りますが その様なものです。
 ISNUMBER関数は、引数が値かどうかが判断できるだけですよね。

 IsNumeric(NO検索)は、引数(変数:NO検索)が値かどうか判断して
 値だった場合に Then の処理へ進みます。
  
(HANA) 2014/10/30(木) 16:12

 >For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row の事です。
 。。。。ΣΣ(゚д゚lll)! またしても。。。。

 エラー処理

 If IsNumeric(NO検索)が数字の場合
   処理A then の処理に進む
  Else
   処理B 何行目に数字じゃないのが入ってる
 End If

 といった感じでしょうか?

 あでも、そうしますとIf IsNumeric(月検索) Then はどうすれば ΣΣ(゚д゚lll)!
 もう一回やらねば(*´ノД`)
(もみじ坂) 2014/10/31(金) 00:08

 アプローチを少し変えて
 実際にどうなるのか確認してみてもらえますか?

 まず、集計シートのA3の値「A01」を削除して下さい。
 これで、1回目のループで「A01」を探しますが、見つかりません。

 test8をステップインで実行しながら
 1回目のループの
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 が終わった時の 変数:NO検索 の値と
              If IsNumeric(NO検索) Then
 で、Thenの方に分岐するか 飛ばしてしまうか 確認して下さい。
  
(HANA) 2014/10/31(金) 08:14

 こんにちは。横から失礼します。

 もみじ坂さんのコードの理解が、フレーズ単位であるように見受けられます。
 たとえば、.Range("A" & Rows.Count).End(xlUp).Row、これを、表の最終行と
 理解しておられるような。

 たしかに最終行(の番号)が返ってくるし、使い方としてはそれであっていますが
 理解の最小単位は「フレーズ」でなく「単語」でないといけないのです。
 単語レベルの理解でないと、応用が利かないのです。

 単語にはひとつひとつ意味と使い方があって、情報は単語から単語へ渡っていって
 フレーズとなり、それで結果としてなんらかの動作が起きるのです。

 「わからないな〜」と思ったときにまず調べるべきは単語です。

( 佳 ) 2014/11/01(土) 19:41


 (HANA)様

 すみませんちょっと行き詰まってますので、
  念のために確認させてください (*´-`*)ゞ ポリポリ

 >アプローチを少し変えて
 >実際にどうなるのか確認してみてもらえますか?

 というのは
 現在のコードで、確認するのか

  If IsNumeric(NO検索)が数字の場合
    処理A then の処理に進む
   Else
    処理B 何行目に数字じゃないのが入ってる
  End If

 を使って実験するのか?
(もみじ坂) 2014/11/01(土) 20:10

 >理解の最小単位は「フレーズ」でなく「単語」でないといけないのです。
 それはあります (*´ノД`) 形を暗記する癖が。。。。

 .Range("A" & Rows.Count).End(xlUp).Row、これを、表の最終行と?
 A列 & 最終行 数えて エクセルの最終セルから 上に向かって

 みたいな意味だと思います。 違いますか(??)

 ただ、この形を思い浮かぶことができないのです。

 .Cells(Rows.Count, 1).End(xlUp).Row
 ですと .Cells(行,列).End(xlUp).Row
 にもともとなっていた明白な意味があるため
 私にとっては分かりやすいのかもです。

 .Cells(最終行を数える,一列目を).End(xlUp).Row

 .Cells(Rows.Count, "A").End(xlUp).Row
 をすると、自分にとってはとってもわかりやすいです。

 なので、「(HANA)様にいつも形にあてはめる」 
 と言われ続けてます (´ロ`ill)

(もみじ坂) 2014/11/01(土) 20:59


 【test8をステップインで実行しながら】
 ってかいたんですが、test8って最初に書いてある以外に
 どこかにありましたっけ?

 それから、ステップインで実行ってわかりますか?

 ↓変数の内容の確認方法も載っているので、ご参考に。
http://hp.vector.co.jp/authors/VA016119/step/step01.html
  
(HANA) 2014/11/01(土) 21:09

 ステップインで実行 で実行したところ エラーになってしまうので、

 >Thenの方に分岐するか 飛ばしてしまうか
 のどちら、でもないようで、戸惑ってました (*´ノД`)

 NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 が終わった時の エラーになってしまします。

 If IsNumeric(NO検索) Then
 にたどり着かない状況です。

 まだ、いろいろ試してますが、
 NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 に行く前に エラー があるかどうか 調べる必要あるような (??)
(もみじ坂) 2014/11/01(土) 21:55

 >ステップインで実行 で実行したところ エラーになってしまうので、
 本当に、test8のコードで実行していますか?

 コードはこちらから貼り付けなおして下さい。

 それから、エラーになるときに メッセージが表示されると思いますが
 どのようなメッセージが表示されるかは重要です。
 何と表示されるのか、こちらにもご説明いただければと思います。
  
(HANA) 2014/11/01(土) 22:56

 >まず、集計シートのA3の値「A01」を削除して下さい。
 A01を削除する前に一回集計してコードが正常に作動していることを確認してます。

 ◆集計シート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]									
[2]	NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
[3]									
[4]	A02								
[5]	A03								
[6]	A04								
[7]	A05								
[8]	A06								

 ◆データーシート

 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[g]	[h]	[g]
[1]	書類NO	日付	TEL	月検索値	NO	NO検索値		単価	cs	pc	金額
[2]	140124 	2014年1月5日	8768 		A01					10 	
[3]	140124 	2014年1月5日	8768 		A01					20 	
[4]	140124 	2014年1月5日	8768 		A04					30 	
[5]	140124 	2014年1月5日	8768 		A04					40 	
[6]	140124 	2014年3月5日	8768 		A03					50 	
[7]	140124 	2014年3月5日	8768 		A05					60 	
[8]	140124 	2014年3月5日	8768 		A05					70 	

 ◆コード
Sub test8()
    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")

    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    '行を再表示させる
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
           月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

              If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
              End If
      Next i

    '空欄の行を非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub

 ◆エラー
 コードを実行する際 「形が一致しません」
 ステップインする際
 NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 の次に行くときに
 「エラー13、形が一致しません」

 と出ました。

 コードはいじってませんよ (´ロ`ill)
 いじる前に確認したんです。。。。。

(もみじ坂) 2014/11/01(土) 23:20


 >>コードはこちらから貼り付けなおして下さい。
 と書きましたよ?

 このページの最初に載せてあるtest8のコード
 ↓戻って確認してください。
 Sub test8()
    Dim NO検索, NO最終行 As Long
    Dim 月検索, 月最終列 As Long

 ↓2014/11/01(土) 23:20に投稿されたコード
Sub test8()
    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long

 違うでしょ?
  
(HANA) 2014/11/01(土) 23:27

 あ ΣΣ(゚д゚lll)! そうでしたね、
 そこを直しました。

 ステップインしたところ
 1順目、2順目は NO検索 の値は エラー 2042 になってます
 3順目 は NO検索 の値は 「6」でした。

 コードを実行して計算させたところ問題なく合計されていました。
 削除したA01を除いて

 Sub test8()
    Dim NO検索, NO最終行 As Long
    Dim 月検索, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")

    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    '行を再表示させる
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
           月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

              If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
              End If
      Next i

    '空欄の行を非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub

 ◆集計シート
 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
[1]									
[2]	NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
[3]									
[4]	A02								
[5]	A03								
[6]	A04								
[7]	A05								
[8]	A06								
 ◆データーシート
 	[a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[g]	[h]	[g]
[1]	書類NO	日付	TEL	月検索値	NO	NO検索値		単価	cs	pc	金額
[2]	140124 	2014年1月5日	8768 		A01					10 	
[3]	140124 	2014年1月5日	8768 		A01					20 	
[4]	140124 	2014年1月5日	8768 		A04					30 	
[5]	140124 	2014年1月5日	8768 		A04					40 	
[6]	140124 	2014年3月5日	8768 		A03					50 	
[7]	140124 	2014年3月5日	8768 		A05					60 	
[8]	140124 	2014年3月5日	8768 		A05					70 	
(もみじ坂) 2014/11/02(日) 00:24

 >1順目、2順目は NO検索 の値は エラー 2042 になってます
 MATCH関数で検索値がなかった場合「エラー2042」になります。

 で、これは数値じゃないですよね。エラー値です。
 だから Dim NO検索 As Long
     変数:NO検索には数値を入れます。
 と宣言しておくと、数値ではない(エラー値)を入れようとする事になるので
 「エラー13、形が一致しません」
 のエラーが出ます。

 今回「形」ってのは「Long」の所の事です。

 Dim NO検索 As Long としておいて、エラーにならない様にするためには
 検索値が一覧にあることを確認して
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 のコードが実行される様にして下さい。

 すでに何度か書いていますが、COUNTIF関数で0より大(まぁ「1」でしょうけど)で
 検索値が一覧にある事が確認できますよね?
  
(HANA) 2014/11/02(日) 01:01

 そうしますと

 Dim NO検索 → 
 データーシート に NO があって
 集計シートに無いときに確認するには ステップインすないと分からない
 普通に計算できるない番号を除いて。

 Dim NO検索 As Long →
 データーシート に NO があって集計シートに無いときは
 エラーメッセージでて、計算が止まる
 COUNTIF関数 で調べてから 処理に進まないといけない

 ですね。

 ◆計算必要ないNO
 やってて思ったんですが、データーシートで、実際計算しなくてもいい
 NOはあります。現在も計算されてないです。
 「ZZZ」「OOO」ですとか その処理も。。。。

 ◆COUNTIF関数
 COUNTIF関数:=COUNTIF(範囲,検索条件)

 [b]	[c]	     [d]	[e]	[f]	[g]
伝票NO	日付	    TEL		NO	COUNTIF
140124 	2014年1月5日	8768 		A01	2     =COUNTIF(E3:E9,E3)
140124 	2014年1月5日	8768 		A01	1
140124 	2014年1月5日	8768 		A04	2
140124 	2014年1月5日	8768 		A04	1
140124 	2014年3月5日	8768 		A03	1
140124 	2014年3月5日	8768 		A05	2
140124 	2014年3月5日	8768 		A05	1

 こんな感じでしょうか?

 その後集計シートと値あるかを比較?

(もみじ坂) 2014/11/02(日) 09:59


 データー.Cells(i, "E")の値が、集計.Range("A:A")の中にあるか確認ですよ?
  
(HANA) 2014/11/02(日) 15:54

 こんにちは。

 > それはあります (*´ノД`) 形を暗記する癖が。。。。
 形を暗記するのはかまわないです。
 というか、実務上は非常に有効ですし、頻繁に使うようなら
 単語登録してもいいくらいです。

 でも単語登録って便利ですけど、応用はしてくれませんよね。
 どっちが正しいかではなく、両方必要ってことです。

 ◆
 単語の意味ですが、
  .Range("A" & Rows.Count).End(xlUp).Row
 .Range(なんちゃら) セルをあらわす。1つのセルだったり複数のセル範囲だったりいろいろ
 .Range("A" & 数値) なら、A列の『数値』行目のセル
 Rows        行(複数形 ただし1行だけの場合も含む)
 .Count       いくつあるか、その数
 Rows.Count     行がいくつあるか、その数
 .End        端っこ。データのある範囲と無い範囲の境目の部分(のうちデータのあるほうのセル)
 (xlUp)       Endの引数。どっち方向に端っこなのかをあらわす。
 .Row        行番号。 ここでは.End(xlUp)で指定されたセルの行番号。

 ちなみに、ここでは「.Range("A" & Rows.Count)」をつかっていますが
 データ件数が絶対に1000件に達しないと分かっていたら
 .Range("A1000")).End(xlUp).Rowでも構わないのです。理屈上は。
 (回答では決してA1000とは書きませんけどね(笑))

 ◆
 単語の意味を理解するには、ヘルプを読まれるといいかなと思います。
   大急ぎで付け加えておくと、「理解できない」のは承知の上です。
   最初はだれでも理解できません。それでもしつこく目に触れさせていると
   少しずつ分かってきます(←実話)。

 単語の上でクリックしてF1キーを押してヘルプを呼び出し、出てきた説明の1行目を読んでください。
 1行目だけで結構です。大事なことは最初に書いてあります。
 「要するにどういうことか」と自問しつつ読んでください。
 (もっと読みたければ2行目以降も読んで構いませんが、無理をすることはありません)
 ネットはこの用途には向きません。情報量が多すぎて、なにが重要か判定しづらいです。

 ※よく知っている単語をあえてヘルプで引いてみると、ヘルプの「ものの言い方」が
  わかって、ほかの単語を読むときの参考になるかもしれません。

( 佳 ) 2014/11/03(月) 12:33


 >データー.Cells(i, "E")の値が、集計.Range("A:A")の中にあるか確認ですよ?
  データーシートにあって 集計シートに無い値 = 0   ?

 [b]	[c]   	[d]	[e]	[f]	[g]
伝票NO	日付	    TEL		NO	COUNTIF
140124 	2014年1月5日	8768 		A01	0      =COUNTIF(Sheet5!$A$4:$A$11,E3)
140124 	2014年1月5日	8768 		A01	0
140124 	2014年1月5日	8768 		A04	1
140124 	2014年1月5日	8768 		A04	1
140124 	2014年3月5日	8768 		A03	1
140124 	2014年3月5日	8768 		A05	1
140124 	2014年3月5日	8768 		A05	1

(もみじ坂) 2014/11/04(火) 16:22


 そういう事なんですが、イメージがうまくついてないですか?

 H列にでも、MATCH関数を入れてみて下さい。
 3,4行目は #N/A のエラーが出ますよね?

 g列が0以外の時にだけ、MATCH関数が計算される様にする
  g列が0以外の行にだけ、MATCH関数を入力すれば
 H列にエラー値が表示されることはないですよね?
  
(HANA) 2014/11/04(火) 19:34

 >そういう事なんですが、イメージがうまくついてないですか?
 どうでしょうか? 大まかは分かりましたが、こまごまなところは手さぐり中です。

 >COUNTIF関数等で調べてからMatch関数が行われる様にしておくのが良いと思います。
 COUNTIF関数はわかりました。

 Match関数? 
 Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
 をエクセル関数にするということでしょうか?

 エクセル関数=MATCH(検査値, 検査範囲, 照合の型)
 照合の型 
 1・・・検査値以下の最大値がヒット 
 0・・・検査値と等しい値がヒット 
 −1・・・検査値以上の最小値がヒット
(もみじ坂) 2014/11/05(水) 00:07

 えっと、今のコードは
           NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
              If IsNumeric(NO検索) Then
 とにかくMATCH関数の結果を 変数:NO検索 に入れて
 そのあと、IFで 変数:NO検索 に数値が入っているかを確認してますよね?

 それを、先に IF で、変数:NO検索 に値が入るかどうか
  (MATCH関数の結果がエラーにならないか=COUNTIF関数の結果が0以外か)を確認してから
 そのあと、MATCH関数の結果を 変数:NO検索 に入れる

 と言う作りに変えるのが目的ですが。
  
(HANA) 2014/11/05(水) 22:16

 そうしますとMATCH関数はこうなりますか?
 あとはIFをいれるだけ

 [b]	[c]	[d]	[e]	[f]	[g]	[h]
伝票NO	日付	TEL	月検索値	NO	COUNTIF	MATCH
140124 	2014年1月5日	8768 		A01	0	#N/A   =MATCH(Sheet6!E3,Sheet5!$A$4:$A$11,0)
140124 	2014年1月5日	8768 		A01	0	#N/A
140124 	2014年1月5日	8768 		A04	1	3
140124 	2014年1月5日	8768 		A04	1	3
140124 	2014年3月5日	8768 		A03	1	2
140124 	2014年3月5日	8768 		A05	1	4
140124 	2014年3月5日	8768 		A05	1	4

(もみじ坂) 2014/11/06(木) 09:24


 ( 佳 )様

 >どっちが正しいかではなく、両方必要ってことです。
  登録するだけで意味が分からなければどこで、使うか分からないと意味ないですよね (´ロ`ill)

 ただ、単語の意味てこんなに細かく理解しないければ行けないのですね......
 いつもだいたいこんな意味しか調べられない私です。

 ネット検索では細かく意味が出ないのですね。
 私のPCは ヘルプ機能がないのです (*´ノД`)

 なのでネットを頼るしかないですが
 参考によさげなページありましたら是非教えてください (*´-`*)ゞ 
(もみじ坂) 2014/11/06(木) 09:30

 ちょっと、どこを目指しておられるのかわかりません。
 MATCH関数の結果は、今までと同じで良い(数式の変更は不要)と思いますが
 替えないとダメなんですか?
  
(HANA) 2014/11/06(木) 09:31

少し横からすいません。HELP機能ですが2010ではただ単語をF1では出ませんがヘルプ機能はあります。
例としてRangeにカーソルを置いてにF1を押してその後右にある検索のドロップダウンリストから下の方の開発者用リファレンスを選択すると単語について出てきます
(デイト) 2014/11/06(木) 09:47

 デイト 様

 ありがとうございます。以前も別の方が教えていただいて
 試しましたが、

 残念ながら、私のPCはもともと特殊なやつのようで、HELP機能は付いていない
 とメーカからの回答がありました (*´ノД`)
(もみじ坂) 2014/11/06(木) 22:54

 > MATCH関数の結果は、今までと同じで良い(数式の変更は不要)と思いますが
 えΣΣ(゚д゚lll)! いいんですか?
 私も (??)しながら悩んでしまいました。

 >g列が0以外の時にだけ、MATCH関数が計算される様にする
 >g列が0以外の行にだけ、MATCH関数を入力すれば

 そうしますと、こうなりますか?
 でもループできてないですし。  データー.Cells(i, "j") がエラーになりますし。
 もう一度整理します (*´ノД`)

 Sub test9()
    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")

    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    '行を再表示させる
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
             カウント = WorksheetFunction.CountIf(集計.Cells(NO最終行, 1), データー.Cells(i, "E"))

             If カウント > 1 Then

                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)
             End If
             If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
              End If

     Next i

    '空欄の行を非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub
 

(もみじ坂) 2014/11/06(木) 23:48


 こんにちは。

 >残念ながら、私のPCはもともと特殊なやつのようで、HELP機能は付いていない
 >とメーカからの回答がありました (*´ノД`) 

 えええええ!
 エクセルを買えばVBAは必ずタダで付いてくるし VBAのヘルプもタダで付いてきますよ。
 パソコンに最初から入っているエクセルも同じです。
 それじゃあエクセル一般機能のヘルプもないんですか?

 VBEでF1キーを押しても、うんともすんとも言わないですか?
 もしヘルプがインストールされていなければ、エクセルはディスクを要求してくるはずですが。

 こんな風にしてみたらどうなりますか?
 ●Excel VBA ヘルプを単独で使用する方法
 http://www.hanatyan.sakura.ne.jp/dotnet/vbahelp.htm

( 佳 ) 2014/11/07(金) 06:12


 佳 様

 ありがとうございます。
 特殊な作りのPCなので、いろいろとあるようです ^^;;

 教えていただいたサイトの通りしてみましたが、開くことができなかったです。
 「コマンドラインの引数が無効です。ホストアプリケーション名または名前空間が定義されていません。」 とでています。

 多分、購入しないと無理です。
 エクセルの HELP同様 その機能自体がないのです。

 なので、PCでのHELP機能云々しようということが、できないと理解しています(*´ノД`)

(もみじ坂) 2014/11/07(金) 18:00


 あ(´ロ`ill)
 エラー処理の回答が出てましたね。。。
 ノートを見直したら発見しました。
 今回はやり方は変わると思いますが。

 カウント関数を使うと書いてありましたので、忘れてました。
 エラー処理は

 カウントの結果と
 On Error GoTo 使用する感じであってますか?

(もみじ坂) 2014/11/07(金) 22:19


 >カウントの結果と
 カウントの結果を利用するのはあってます。
             If カウント > 1 Then
 ですよね。
  これだと、1より大=1だった場合はfalse になるのでダメですが。

 > On Error GoTo 使用する
 On Error GoTo を使わなくて済む様に、countifの結果を使うのです。

 まぁ、まずは
             カウント = WorksheetFunction.CountIf(集計.Cells(NO最終行, 1), データー.Cells(i, "E"))
 の式は正しくないので、直して下さい。                  ~~~~~~~~~~~~~~~~~~
  
(HANA) 2014/11/07(金) 23:12

 こんにちは。
 ヘルプの件、了解です。 代替案を2つご案内しましょう。

 MSDNのサイトは、ヘルプと同等と言われています。
 こちらです。
  ・http://msdn.microsoft.com/ja-jp/library/cc427093.aspx
 右上の検索窓に単語を入力して検索できます。

 書籍ならこの二冊。古本屋さんなどで安く見かけられたらどうぞ。
 amazonで検索したらとてつもない値段がついていました(^^;
  ・Excel2000 VBAリファレンス (Office2000・Visual Basicランゲージリファレンス)
  ・Excel2000 VBAハンドブック (ナツメ社ハンディ・リファレンス) 
 ヴァージョンが古いですが、基礎的なところは変わっていないので大丈夫です。
 最近の本は、口当たりが良すぎて、ヘルプの代用としてはわたしはお勧めしません。

( 佳 ) 2014/11/08(土) 09:07


 多分答えと近いと思いますが.....
 あとA01をエラー値にしますと、しょっぱなからエラーになって
 検証できないので、A04をエラー値にしました。

 ◆集計シート
 [a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
A01				30 				30 
A02								
A03						50 		50 
A05						130 		130 

 ◆データーシート

 [b]	[c]	[d]	[e]	[f]	[g]
伝票NO	日付	TEL	月検索値	NO	COUNTIF
140124 	2014年1月5日	8768 		A01	1   =COUNTIF(Sheet5!$A$3:$A$11,E3)
140124 	2014年1月5日	8768 		A01	1
140124 	2014年1月5日	8768 		A04	0
140124 	2014年1月5日	8768 		A04	0
140124 	2014年3月5日	8768 		A03	1
140124 	2014年3月5日	8768 		A05	1
140124 	2014年3月5日	8768 		A05	1

 ◆コード
 ★の部分がちょっとまだ理解してませんが、
 &ここの場合は .Cells をうまく使えませんでした。 (*´ノД`)
 これも合わせて引き続き検証します。
 ▲の部分は行数ではなく NO 番号表示する方法に変更したいです。

 Sub test9()
    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")

    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    '行を再表示させる
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & NO最終行), データー.Cells(i, "E")) '★

            If カウント = 1 Then

                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

               If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")
                 End If
                End If
             Else
                  MsgBox i & "行目のNOが登録していません。"    '▲       

            End If
     Next i

    '空欄の行を非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>" 

 End Sub
(もみじ坂) 2014/11/09(日) 00:40

 佳 様

 ありがとうございます。ヾ(@^∇^@)ノ

 そんな便利なサイトあったんですね
 これからは、重宝してみます ( *´艸`)クスクス
 大変助かりました。
 http://msdn.microsoft.com/ja-jp/library/cc427093.aspx

 本は.....購入は辞退したいと思います (*´-`*)ゞ ポリポリ
(もみじ坂) 2014/11/09(日) 00:56

 >★の部分がちょっとまだ理解してませんが、
 どのあたりが曖昧でしょうか?

 >&ここの場合は .Cells をうまく使えませんでした。 (*´ノД`)
 該当行より上側に、同じような部分はあるんですけどね。

 >▲の部分は行数ではなく NO 番号表示する方法に変更したいです。
 そうですね。
 ここも、同じ部分はあるのですが。

 >If カウント = 1 Then
 ってやると、二つ登録されていた時も FALSE なので
 「登録していません」って表示されちゃいますよ?

 また、A04はデータが2件ありますので 2回「A04のNOが登録していません。」と出てしまいますね。

 同じメッセージボックスが複数回表示されてしまうのは、少し後回しにして
 COUNTIFのあたりとか、NOを表示させるとかできたら
 もう少し処理の方を見直していきたいと思います。
  
(HANA) 2014/11/09(日) 01:02

 >どのあたりが曖昧でしょうか?

 集計.Range("A3:A" & NO最終行)です。
 見つけたのはいいのですが、始めてみるフレームなので理屈がわく分からなかったです。

 集計.Range("A3:A" )だけではだめなんですね。
 A3〜A列 これですと エラー 「400」とでちゃいました。

 A3:A列の最終行をを指定する のが 1フレームみたいなのかな?と思い

 集計.Range("A3:A" & Rows.Count)

 しても、全然OKでしたので、1フレーム と結論付けたんですが、
 そんな感じですか?

 >ここも、同じ部分はあるのですが。
 同じこれのことですか? 
 集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

 >二つ登録されていた時も FALSE なので
 二つ? とはなんでしょうか?
 今のところは2回メッセージが出ただけで、特に何もないですが、
 いろんな状況を想定して検証してみます。
 If カウント <> 0 Then
 これもにたりですものね、、、、

 >同じメッセージボックスが複数回表示されてしまうのは、少し後回しにして
 了解です。

 > COUNTIFのあたりとか、NOを表示させるとかできたら
 う〜ん現在考え中です。 NO。。。NO。。。A列を読みにいかないといけないですよ  ね。。。

(もみじ坂) 2014/11/09(日) 23:15


 >見つけたのはいいのですが、始めてみるフレームなので理屈がわく分からなかったです。
 2014/10/28(火) 23:33 で、納得して頂けたと思っていましたが。

 A3〜A10の範囲を表したければ
 Range("A3:A10")ですよね?

 今回「10」の所が 変数:NO最終行 なので
 Range("A3:A" & NO最終行)です。

 A3〜A10の範囲を表そうとするのに
 Range("A3:A")とは書かないと思います。
 こんな記述をされたんじゃ、もみじ坂さんだって、どこの範囲かわからないですよね?

 一番簡単な記述をまず思い浮かべて下さい。
 「どの様に書かないといけないのか」骨格となる部分を一番にとらえる事を考えて下さい。
 骨格がしっかりしていないので、うまくいかなかった時に
 考えがあっちへ行ったり こっちへ行ったり してしまうのだと思います。

 >同じこれのことですか? 
 >集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents
 そうです。3行目&5列目のセルから NO最終行&月最終列のセル 範囲をClearContentsですよね。

 今回は、  3行目&1列目のセルから NO最終行&1列目のセル範囲が、COUNTIF関数の範囲です。

 >>二つ登録されていた時も FALSE なので
 >二つ? とはなんでしょうか?
 集計シートのA列に、手違いでダブって入力されていた場合です。

 その場合、変数:カウント には「2」が入ります。
 ですから、If カウント = 1 Then では、2=1 の評価なので、FALSE(Elseの方)へ分岐し
        「登録されていません」とメッセージが表示されます。
 これを、  If カウント <> 0 Then にしたら、 2<>0 なので、TRUE へ分岐します。

 >NO。。。NO。。。A列を読みにいかないといけないですよ  ね。。。
 A列ですか?どのシートの?
 「集計シートのA列にその値は有りません」と表示するんですよね?
 でしたら、集計シートのA列を探しても、その値は無いと思いますが。
  
(HANA) 2014/11/10(月) 12:02

 >今回「10」の所が 変数:NO最終行 なので
 なるほどそういう意味だったんですね。了解です。

 >If カウント <> 0 Then
 こちらの方が0以外でしたらOKですね、

 >その値は無いと思いますが。
 ないのですか。。。まだやってないので分からないですが、
 では、表示方法を見つけなければ。
 エラー処理考えると他にももろもろ追加しないといけないですね。
 勉強のためにやった方がいいですが、

 いっそ データーシートのNOをダブらない項目でフィルターかけて 
 集計シートの A列に転記させてから計算させたほうが、
 シンプルにできる気がするんですが、
 気のせいでしょうか (*´-`*)ゞ

(もみじ坂) 2014/11/11(火) 00:44


 >ないのですか。。。まだやってないので分からないですが、
 いや、「あると思っている」なら、私のイメージともみじ坂さんが言っておられるイメージが
 違うのだと思います。

 今 集計シートから、A04 が消してあると思いますので
 5行目の処理を考えた時 何と表示したいと思っているのか
 教えて下さい。

 >データーシートのNOをダブらない項目でフィルターかけて 
 >集計シートの A列に転記させてから計算させたほうが、
 集計しなくて良いNOがあるんですよね?
 「 ◆計算必要ないNO
   やってて思ったんですが、データーシートで、実際計算しなくてもいい
   NOはあります。現在も計算されてないです。
   「ZZZ」「OOO」ですとか その処理も。。。。」
 と言うお話だったと思いますが。
  
(HANA) 2014/11/11(火) 08:45

 こんにちは。

 >そんな便利なサイトあったんですね
 >これからは、重宝してみます ( *´艸`)クスクス 

 大切なことなので、もう一度書きます。
 そのサイトを読んでみて理解できなくてもがっかりしないでください。
 最初は、わけが分からないのが普通です。
 ヘルプの難解さには定評があります。
 にもかかわらず、しつこく読み続けているとだんだん分かってきて
 それなしではコードを書けなくなるのがヘルプです。
 重宝してください。

( 佳 ) 2014/11/11(火) 19:25


 >5行目の処理を考えた時 何と表示したいと思っているのか
 集計シートに抜けているNOを表示させたいです、
 現在は行数になってます、

 >集計シートのA列を探しても、その値は無いと思いますが。
 HANA 様 が言いたいことが分かりました。

 MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"
 ですと A03のNOとA05のNO がないとメッセージが出ました。
 ないのは A04 を表示させたくても 記載してないですもの、表示させようがないですね (*゚Å゚;*) 

 データーシートを参照しないと意味ないですね。
 MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"

 改めて思います。
 言葉を読むだけでは状況を把握するのは難しいですが、
 やってみると一目瞭然ですね。

 >と言うお話だったと思いますが。
 はい、不要なものは多分4〜6このNOがあるぐらいです。
 手数料ですとか、送料ですとか、1回しか注文してないNOですとか
 そういうNOはあっても無くても特に重要ではないです。^^;;

 すみません≧≦私やり方はあまりこだわらずにいたので、
 目的は、欲しいデーターの合計が見れればOKです。
 &容量を節約したい。 ただ、その2点だけです。

 なので、どちらのやり方でもOKです。 (*´-`*)ゞ

(もみじ坂) 2014/11/12(水) 00:24


 佳 様

 >重宝してください。
 はい 柱|皿 ̄)q
 早速使わせていただいてます。

 最初は検索結果が多いすぎて、よくわからなかったですが、
 だんだん慣れてきました。
 検索の言葉を工夫したり、題名見て似たりのもののみ開いて読んだりしてます。

 ホントありがとうございました。
(もみじ坂) 2014/11/12(水) 00:29

 コードとしては
  MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"
 で良いと思います。

 でも、そこへたどり着く道筋はもう少し整理した方が良いと思います。

 >集計シートに抜けているNOを表示させたいです、
 >現在は行数になってます、
 これは
 >>5行目の処理を考えた時 何と表示したいと思っているのか 
 の答えになっていません。
 何行目の処理であっても「集計シートに抜けているNOを表示させたい」ですよね?
 ~~~~~~~~~~~~~~~~~~~~~~
 そうではなく、【5行目の処理を考えた時】何と表示したいと思っているのか 答えて下さい。
  
(HANA) 2014/11/12(水) 10:14

 >【5行目の処理を考えた時】何と表示したいと思っているのか 答えて下さい。
 の意味がよくわかりません。

 5行目処理終わった現在は結果しか表示されてません。

 う〜ん (○ ̄ 〜  ̄○;)ウーン・・・
 抜けてるNOを処理の途中に表示させるではなく。
 処理後に、抜けてる番号を全部いっぺんに表示させるとか? でしょうか?
(もみじ坂) 2014/11/12(水) 15:53

 5行目のE列のNOは「A04」で、A04は一覧シートのA列にはないので
 「A04のNOが登録していません。」
 と表示したいんじゃないんですか?

 MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"
 は、そう表示する様になっているとおもいますが。
  
(HANA) 2014/11/12(水) 16:16

 >と表示したいんじゃないんですか?
 そうですね。現在のコードはそうなります。

 ◆集計シート
     [a]	[b]	[c]	[d]	[e]	[f]	[g]	[h]	[K]
 [2] NO	   商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
 [3] A01				 30 				 30 
 [4] A02								
 [5] A03						 50 		 50 
 [6] A05						130 		130 
(もみじ坂) 2014/11/12(水) 18:16

 >現在のコードはそうなります。
 本当はそうしたいんじゃないってこと?
  
(HANA) 2014/11/12(水) 20:56

 (HANA)様がなにを言いたいのかが分からないだけです。

 >「集計シートに抜けているNOを表示させたい」
 >【5行目の処理を考えた時】何と表示したいと思っているのか

 コードの処理の上では意味合いが違うかもですが、
 私にとって上の二つの結果は同じです。
  A04 がないから メッセージで表示させること。

 MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"
 で その結果を得ることができた 

 >【5行目の処理を考えた時】何と表示したいと思っているのか
 A04のNOを表示させること

 な感じです。
(もみじ坂) 2014/11/12(水) 21:06

 >なにを言いたいのかが分からないだけです。
 2014/11/12(水) 10:14で書いていますが、コード自体は、作成された
  MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"
 で良いと思います。

 そこにたどり着いた道筋が良くないと思います。

 >5行目のE列のNOは「A04」で、A04は一覧シートのA列にはないので
 >「A04のNOが登録していません。」と表示したい
 時の~~~が、どこから来ているかというと、5行目のE列のNOが「A04」だからですよね?

 3行目は「A01」ですが、もしも A01が一覧シートのA列になかったら
 「A01のNOが登録していません。」と表示したいですよね?
 このメッセージの「A01」は、やはり3行目のE列のNOが「A01」だからです。

 カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & NO最終行), データー.Cells(i, "E")) 
 COUNTIF関数の結果が「0」と言う事は、COUNTIF関数の検索条件にした値・・~~~~~~~~~~~~~~~~~~~~~このセルの値
 が、集計シートのA列にないからです。

 だから、「"下線部のセルの値"のNOが登録していません。」と表示されれば良い。
 下線部のセルの値は データー.Cells(i, "E") なので
 MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"
 のコードが完成します。

 >MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"
 >ですと A03のNOとA05のNO がないとメッセージが出ました。 
 これを「やってみた」と言うのが、そこへたどり着く道筋が良くないと思っている原因です。

 そもそも、変数「i」はデータシートのループに関係する値で、集計シートに関係する値ではないです。
 なので、データシートのどこかの列に対して「i」を使って何かのメッセージを表示させようとやってみたならまだ。。。

   それだって、COUNTIF関数で「データー.Cells(i, "E").Value」を探してそれがなかった事を確認しているのですから
   メッセージボックスにも データー.Cells(i, "E").Valueがない と表示すれば良いと思い到って欲しいと思いますが。

 コードを書くには
  1.どうなった時に、どうしたいか言葉にしてみる
  2.処理の流れを考える
  3.実際にその考えに沿って処理してみる
  4.コードにする
  5.検証する
 です。

 1番目が
 >5行目のE列のNOは「A04」で、A04は一覧シートのA列にはないので
 >「A04のNOが登録していません。」と表示したい
 「A04」のありかが E5 だという事は、このように考えられれば
 悩まなくてもわかると思います。
  
(HANA) 2014/11/12(水) 22:09

 回答が セル番地 だんたんですね (*´ノД`)
 結果のメッセージは NO を表示してたので、 
 私の頭には A04 が回答と思い込んでました。

 データー.Cells(i, "E")
 確かに、検索値もセル番地ですね

 私のコードを書くは
  1.どうなった時に、どうしたいか言葉にしてみる
  4.コードにする
  5.検証する 結果でた OK 終わり
 こんな感じですね。

 メモに追加しておきます (´゚д゚`)

 >>MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"
 こちらが原因ですね。
 これを使った後に HANA 様 が 集計シートは A04 の値がないよ〜 と言われて

 → 集計シートに答えはもともとない 、じゃ答えはどこ?
 → データーシートの E5とE6 だよ
 → その回答になるよう MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。" に変更
 → 欲しい答えでた OK 
。

 と最初に書いておけばよかったんですね
 コードしか書いてませんでした。すみません ≧x≦

ただ、自分でやっといてなんなんですが、
このメッセージの表示方は非常に効率が悪いと思ってしまうのは気のせいでしょうか?

(もみじ坂) 2014/11/13(木) 00:37


 >回答が セル番地 だんたんですね (*´ノД`)
 何の回答ですか?

 >>5行目の処理を考えた時 何と表示したいと思っているのか
 の質問の答えとして期待しているのは
 >>「A04のNOが登録していません。」
 です。

 少しずつ聞くと、ゴールが見えなくて戸惑っておらっる様ですし
 全てを書くと、焦点が曖昧になってしまう様です。
   文字にする段階で、曖昧になってしまっているのかもしれませんが。

 「5行目のNOが登録してません。」ではなく
 「A04のNOが登録していません。」と表示したい
 と言うお話でしたよね?

 「5行目のNOが登録してません。」であれば、「MsgBox i & "行目のNOが登録していません。"」で良かったです。
 「A04のNOが登録していません。」を考えた時に、「Msgbox ●●● & "行目のNOが登録していません。"」の
 ●●●部分がわからなかったのですよね?

 このメッセージに表示させるために「A04」を探したら
 データシートに無いことは コードを作ってみるまでもなくわかったと思います。

 そもそも、なんで集計シートに有るとおもったんですか?
 「●●は集計シートにないですよ」と言うメッセージの「●●」が
 集計シートに有るわけが無いですよね。
 集計シートに●●があるなら、メッセージを表示する必要が無いのですから。

 最初に
  よく考えて MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。" をやってみて
  うまくいったからOK
 これは、OKです。

 最初に
  よく考えて MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"をやってみて
  うまくいかないから、今度は
  MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。" をやってみて
  うまくいったからOK
 は、OKではありません。

 ただし、「どうして最初に間違えたのかを検証して、正す」事が出来れば OK だと思います。

 >と最初に書いておけばよかったんですね
 「今度は〜」の部分はどちらかと言うとどうでも良いです。
 実際コードはご自身で作成できたのですから。

 私が気にしているのは、最初になぜ間違えてしまったか、過去の自分と向き合ってみたか? と言う事です。

 >私のコードを書くは
 > 1.どうなった時に、どうしたいか言葉にしてみる
 > 4.コードにする
 > 5.検証する 結果でた OK 終わり
 >こんな感じですね。 
 と言うことは「1」は出来ていると考えておられるのですか?
 >>5行目のE列のNOは「A04」で、A04は一覧シートのA列にはないので
 >>「A04のNOが登録していません。」と表示したい 
 これは、「1」に含まれるのですが 本当に出来ていましたか?

 >「集計シートに抜けているNOを表示させたい」
 では不十分です。
 この言葉の中に「集計シート」がでてくるから「集計シートのA列を・・・」と
 考えてしまったのではないかと推測しますが、どうでしょう?

 >このメッセージの表示方は非常に効率が悪いと思ってしまうのは気のせいでしょうか?
 どういう点で、効率が悪いと思いますか?
  
(HANA) 2014/11/13(木) 09:38

 > >>5行目の処理を考えた時 何と表示したいと思っているのか

 5行目のE列のNOが「A04」だからですよね? と書いてありましたので、
 E5 がこたえかと。。A04 がそこにあるので、

 > >>この言葉の中に「集計シート」がでてくるから「集計シートのA列を・・・」と
 > >> 考えてしまったのではないかと推測しますが、どうでしょう?

 まさに、その通りです。

 >私が気にしているのは、最初になぜ間違えてしまったか、過去の自分と向き合ってみたか? と言う事です。
 >「集計シートに抜けているNOを表示させたい」では不十分です。
ではなく

 説明文を読むとどれもコード作成以外は
 全部中途半端な解釈なんですね。
 考えが中途半端なので、処理の流れも作成コードも、迷いが起きるんですね。
 これも、慣れだと思いますが、メモっておきます。
 言葉足らずのところも、少なくはないかなと。。

 >このメッセージの表示方は非常に効率が悪いと思ってしまうのは気のせいでしょうか?

 まだ。実のデーターを試してないので、わからないですが。
 たとえば、10個の登録してないNOがあるとして(ダブりはさておき)
 計算のとちゅうで10回もメッセージが表示されるんですよね。

 for nextは1行ずつ処理する方法なので、仕方ないとして

 【「A04のNOが登録していません。」は計算が全部終わってから表示させる 】

 そのほうが途中で、10回表示させるより、スマートかなと思ったんです。
 一般的にどうなんですか?

(もみじ坂) 2014/11/13(木) 16:33


 こんにちは。

 このスレッドの最初にこう書いてあります。 

 >◆今回の課題
  (中略)
 >   また、検索値が無かった場合にどうするのかも決めておいてもらえると良いと思います。
 >   無かったものは集計しないのか
 >   処理を中断して、追加してもらって もう一度実行してもらうのか」

 これが決まらないから、仮に、メッセージボックスを出しているのではないですか。
 あと、勉強もかねているんじゃないでしょうか。

 >一般的にどうなんですか?
 検索値が無かった場合にどうしたいのかによって、適切なやり方は変わります。

( 佳 ) 2014/11/13(木) 21:57


 >このスレッドの最初にこう書いてあります。
 そうですね。使い方によってですよね
 困ったです。どうしましょう?

  ただ、考え方を変えると、1からコードを組み替えることになりますよねキット。。
 ここまできて、それは悲しいので、このままにしようかな (*´ノД`)
 課題ですので、道をそれちゃいけないですよね。。前に進めない。
 このままで進みたいと思います。

 >これが決まらないから、仮に、メッセージボックスを出しているのではないですか。
 それもありますが、コードの実行の確認のためが一番最初の目的でした。

(もみじ坂) 2014/11/13(木) 23:05


 >これも、慣れだと思いますが、メモっておきます。
 そうですね。慣れるとそんなに細かく考えなくても組み立てられる様になると思いますが
 それまでは、一処理ずつ(1行ずつ)言葉にして考えて下さい。

 最初の時もやりましたよね?
  3行目に関して、集計シートの何行目に「NO」があるか・何列目に「月」があるか確認して、クロスするセルに値を足し算する。
  4行目に関して、・・・・
  5行目に関して、・・・・
 実際に手を動かしてもらったと思います。

 今回はそれをしていませんよね?
 面倒ですが、やるようにしてもらうのが良いと思います。

 >たとえば、10個の登録してないNOがあるとして(ダブりはさておき)
 >計算のとちゅうで10回もメッセージが表示されるんですよね。
 そうですね。
 しかも、集計しなくて良いとわかっているNOについてもメッセージが出ますので
 やはりよろしくないでしょうね。

 2014/11/09(日) 01:02 で
 >同じメッセージボックスが複数回表示されてしまうのは、少し後回しにして
 >COUNTIFのあたりとか、NOを表示させるとかできたら
 >もう少し処理の方を見直していきたいと思います。
 と書きましたが、メッセージボックスに関してはそのくらいにして
 コードの主要部分に話を戻しても良いでしょうか?
  
(HANA) 2014/11/13(木) 23:46

 はい、よろしくお願いします。

 場合によってこの処理を違うところにも使いたいので是非 柱|皿 ̄)q
(もみじ坂) 2014/11/14(金) 00:54

 じゃぁ、気を取り直して もう一度コードをじっくり読んで下さい。 

 着目点は  Dim NO検索 As Long の様に、変数の型を「Long」にした事です。

 Longで宣言しているので、コードがエラーで止まっていなければ
 変数:NO検索 には必ず数値が入っています。

 なのに、変数:NO検索 に数値が入っているかどうか確認するのは変ですよね?

 今は、処理のまとまり毎にコメントが入れてありますが
 全ての行にコメントを入れてみて下さい。
 問題点がわかりやすくなると思います。
  
(HANA) 2014/11/14(金) 11:44

 >なのに、変数:NO検索 に数値が入っているかどうか確認するのは変ですよね?
 言われてみればそうですね。 ^^;;
 ただ、目先のことをやるだけで精いっぱいな私には気づきませんでしたが "(-""-)"

 >全ての行にコメントを入れてみて下さい。
 ▲のところにもコメント入れるてことですか?

 If カウント = 1 Then
                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)
               If IsNumeric(NO検索) Then
                 If IsNumeric(月検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")
         ’▲ここにもコメント
                 End If
                End If
             Else
                  MsgBox i & "行目のNOが登録していません。"    '▲       
            End If
(もみじ坂) 2014/11/14(金) 13:45

 全ての行 です。

 If カウント = 1 Then ・・・・の行
 NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0) ・・・の行
 月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0) ・・・の行
 If IsNumeric(NO検索) Then ・・・の行
  
(HANA) 2014/11/14(金) 14:11

 こんな感じでしょうか?
 必要ないところをちょっと削除しました。
 データーシートにある7個のNOが7回のメッセージで知らせてくれました。
 [●●のNOが登録しています。]

 [b]	[c]	    [d]	  [e]	[f]	[g]
 伝票NO	日付	    TEL	 	NO	COUNTIF
140124 	2014年1月5日	8768 		A01	1
140124 	2014年1月5日	8768 		A01	1
140124 	2014年1月5日	8768 		A04	0
140124 	2014年1月5日	8768 		A04	0
140124 	2014年3月5日	8768 		A03	1
140124 	2014年3月5日	8768 		A05	1
140124 	2014年3月5日	8768 		A05	1

 Sub test10()
    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    Set 集計 = Worksheets("Sheet5")
    Set データー = Worksheets("Sheet6")

    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    '月別合計
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))

            If カウント <> 0 Then

                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

               If IsNumeric(NO検索) Then
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
                    MsgBox データー.Cells(i, "E").Value & "のNOが登録しています。"
                End If
            End If
     Next i

 End Sub
(もみじ坂) 2014/11/14(金) 19:11

 こんにちは。

 >ただ、考え方を変えると、1からコードを組み替えることになりますよねキット。。
 ケースバイケースですね。
 どこまで現在のやり方と違うことを考えておられるのか。

 ともあれ、現在のコードを生かし、なおかつ、検索値が無かった場合の対応も行うことはできますよ。
 (というか、できないならそもそもHANAさんがここまで誘導してこられるはず有りません。)

 検索値が無い場合は何もしないってわけには行かないでしょうから、いずれ、なにか対応する
 ことになると思います。そのときに向けて、どうなってほしいのか、考えておかれるといいと
 思います。

( 佳 ) 2014/11/14(金) 20:44


 >そのときに向けて、どうなってほしいのか、考えておかれるといいと思います。

 ありがとうございます。+。:.゚(人〃∇〃)*
 もう少し様子を見て決めたいと思います。

(もみじ坂) 2014/11/14(金) 21:09


 >こんな感じでしょうか?
 いや、違います。。。

 >>全ての行にコメントを入れてみて下さい。
 の「コメント」ってのは
   ↓の部分だと
   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

 上側の「'値クリア」の事です。
 下側のコードが、何をしているかの説明ですよね?

 「'月別合計」とコメントがありますが、これは それに続く数行がやっていることを
 まとめたコメントになっています。

 そうではなく、一行ずつコメントをつけてみて下さい。
  
(HANA) 2014/11/14(金) 22:44

 はずれですか (´ロ`ill) すみません。

 コメントとは
 コードの説明分のことでしょうか?

 Sub test11()

' 整数型 Integer 2         -32,768〜32,767
' 長整数型 Long 4         -2,147,483,648〜2,147.483,647
' 日付型       Date  8         西暦100年1月1日〜西暦9999年12月31日
' オブジェクト型   Object  4         オブジェクトを参照するデータ型
' 文字列型     String  10+文字列の長さ 0〜2GB
' バリアント型   Variant  16       すべてのデータを扱えるデータ型で0〜2GB

    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    'Sheet5の変数
    Set 集計 = Worksheets("Sheet5")
    'Sheet6の変数
    Set データー = Worksheets("Sheet6")

    'A列の入力されているデータの最終セルを取得する(エクセルの最終行から上に向かっての最終行)
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row

    '2行目の入力されているデータの最終列を取得する(エクセルの最終列から左に向かっての最終列)
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    'フィルターをクリアする
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    'For〜Nextは条件により繰り返えして処理をする(3行目から値がある最終行まで)
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row

            '集計シートにデーターシートと同じ値があるかを調べる(0=なし、1=1個ある、2以上はダブってる)
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))

            'カウントの結果が0と等しくないとき(1以上のとき)
            If カウント <> 0 Then

                'Noが集計シートの何行目に有るかMATCH関数で調べる
                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

                '日付から月部分を取り出して、集計シートの何列目に有るかMATCH関数で調べる
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

               'IF関数を使って条件を付ける(NOと月の値がある時のみ処理する)
               If IsNumeric(NO検索) Then

                'セルの値が数値かどうかを判断する
                 If IsNumeric(月検索) Then

                    '集計シートの何行目に「NO」があるか・何列目に「月」があるか確認して=クロスするセルに値を足し算する。
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")

                    '集計シートの何3行目〜最終行まで1行ずつ= 最終列のセルにNOの値を足し算する。
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
                End If

             'カウントの結果が0と等しいとき(1以下のとき)
             Else

                   '●●&のNOが登録しています。
                   MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"

            End If
     Next i

    '合計値のない空欄の行をフィルターで非表示させる
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub
(もみじ坂) 2014/11/15(土) 00:22

 >コメントとは
 >コードの説明分のことでしょうか?
 そうそう、それの事です。

 それで、すみませんが
 分かっておられる所と、分かっておられない所がわからないので
 もう少しコードがイメージできる説明文を書いてみてもらえますか?

    'Sheet5の変数 → 「集計」にSheet5をSetする
    Set 集計 = Worksheets("Sheet5") 

    'A列の入力されているデータの最終セルを取得する(エクセルの最終行から上に向かっての最終行)
     →〜〜〜取得して「NO最終行」に入力する
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
 みたいな感じで。
 もう少しコードに近づけるなら
     「NO最終行」に 〜〜〜を取得して入力する
 でしょうか。 

 また
            'カウントの結果が0と等しくないとき(1以上のとき)
            If カウント <> 0 Then
 と書くのなら
                'セルの値が数値かどうかを判断する
                 If IsNumeric(月検索) Then
 も同じ様に書いて下さい。
         「月検索」の値が数値のとき
 とかになると思います。
   「月検索」は変数で、セルではないので 書いておられるコメントをみると
   ちゃんとコードを見て文字にしているのかな? と不審に思ってしまいます。 

 それから、細かい事ですが 1以上 は「1」が含まれます。
 そして、1以下 も「1」が含まれます。
 1より未満 で「1」は含まれません。
  1以上は >=1
  1以下は <=1
   1未満は <1
  
(HANA) 2014/11/15(土) 11:11

 こんな感じでしょうか? なんとなくわかっていても、
 いざ説明すると難しいですね _〆(・v・★)

 Sub test11()

 ' 整数型             Integer
 ' 長整数型           Long
 ' 日付型       Date
 ' オブジェクト型   Object
 ' 文字列型       String
 ' バリアント型     Variant

    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    '「集計」にSheet5をSetする
    Set 集計 = Worksheets("Sheet5")

    '「データー」にSheet6をSetする
    Set データー = Worksheets("Sheet6")

    'NO最終行 に 入力されているデーターの最終セルの行数を取得し代入する
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row

    '月最終列 に 入力されているデーターの最終列の列数を取得し代入する
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    'A2〜最終列・行を取得して、最終列のフィルターをクリアする
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   '値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    'For〜Nextは条件により繰り返えして処理をする(3行目から値がある最終行まで)
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row

            '集計シートにデーターシートと同じ値があるかを調べる(0=なし、1=1個ある、2以上はダブってる)
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))

            'カウントの結果が0と等しくないとき(1以上のとき)
            If カウント <> 0 Then

                'NO検索 に Noが集計シートの何行目に有るかMATCH関数で取得して代入する
                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

                '月検索 に 日付から月部分を取り出して、集計シートの何列目に有るかMATCH関数で取得して代入する
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

               'セルの値が数値かどうかを判断する
               If IsNumeric(NO検索) Then

                'セルの値が数値かどうかを判断する
                 If IsNumeric(月検索) Then

                    '集計シートの何行目に「NO」があるか・何列目に「月」があるか確認して=クロスするセルに値を足し算する。
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")

                    '集計シートの何3行目〜最終行まで1行ずつ= 最終列のセルにNOの値を足し算する。
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
                End If

             'カウントの結果が0と等しいとき(1未満のとき)
             Else

                   '●●&のNOが登録しています。
                   MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"

            End If
     Next i

    'A2〜最終列・行を取得して、最終列が空欄の時非表示する
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub
(もみじ坂) 2014/11/16(日) 23:01

 >いざ説明すると難しいですね _〆(・v・★)
 そうですね。
 でも、私が思うコードの書き方は
  説明文→コード
 だと思っています。

 「集計シートにデーターシートと同じ値があるかを調べたい!!」
 と思うから
 「じゃあ、どうやって調べよう。FINDで探そうか。MATCH関数でエラーだったら値が無いけど。COUNTIF関数で数を数えてもわかるか。。。」
 と考えて
 「COUNTIF関数が簡単そうだから、これで行こう」
   ↓
  WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))
 の式が出てきます。
 この式を知っているから、集計シートにデータシートと同じ値があるか調べたいと思ったわけではありません。 

 説明文=処理の流れ ですから、思った動きをしない時に
 説明文(処理の流れ)が悪いのか、コードの書き方が悪いのか
 問題点が見つけやすくなると思います。

 いま、もみじ坂さんは 処理の流れが明確でない中、不明瞭なままコードを作ってテストしている。
 だから、うまくいかない時に、処理方法が悪いのにコードを変えてみたり
 コードが悪いのに処理方法を変えてみたりしている様に思います。

 以下、もう少し見直してみて下さい。(同じ様な所がいくつかありますが)

    'A2〜最終列・行を取得して、最終列のフィルターをクリアする
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

 この行で、最終列・最終行は取得してませんよね?
 説明文から、コードにすると
    集計.Range(集計.Cells(2, 1), 集計.Cells(集計.Cells(Rows.Count, 1).End(xlUp).Row, 集計.Cells(2, Columns.Count).End(xlToLeft).Column)).AutoFilter Field:=月最終列
 になりませんか?

 細かいルール(どんなコードを意図している時に、どんな言葉で説明するか)は
 ご自身で決めてもらえたら良いと思いますが。

 あぁ、それから
 >>なのに、変数:NO検索 に数値が入っているかどうか確認するのは変ですよね?
 >言われてみればそうですね。 ^^;;
 納得されたのであれば、そろそろ変更して下さい。
  
(HANA) 2014/11/17(月) 09:08

 > いま、もみじ坂さんは 処理の流れが明確でない中、不明瞭なままコードを作ってテストしている。

  たしかにそうですね。
  コードに対しても、メモってたはずなのに、認識違いとかも出てきたりします。
  コードの理解も 知ってるつもり で、 明確にわかる ではない と認識しました。

 >納得されたのであれば、そろそろ変更して下さい。
  (??) エラー値を検索するのですか?

 >以下、もう少し見直してみて下さい。(同じ様な所がいくつかありますが)

  範囲を取得でしたね 「最終行」なので勘違いしてました (´ロ`ill)

 Sub test11()

 ' 整数型             Integer
 ' 長整数型           Long
 ' 日付型       Date
 ' オブジェクト型   Object
 ' 文字列型       String
 ' バリアント型     Variant

    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    '「集計」にSheet5をSetする
    Set 集計 = Worksheets("Sheet5")

    '「データー」にSheet6をSetする
    Set データー = Worksheets("Sheet6")

    'NO最終行 に 入力されているデーターの最終セルの行数を取得し代入する
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row

    '月最終列 に 入力されているデーターの最終列の列数を取得し代入する
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    'A2〜データーの範囲を取得して取得して、最終列のフィルターをクリアする
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   'E3〜データーの範囲を取得して値クリア
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    'For〜Nextは条件により繰り返えして処理をする(3行目から値がある最終行まで)
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row

            '集計シートにデーターシートと同じ値があるかを調べる(0=なし、1=1個ある、2以上はダブってる)
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))

            'カウントの結果が0と等しくないとき(1以上のとき)
            If カウント <> 0 Then

                'NO検索 に Noが集計シートの何行目に有るかMATCH関数で取得して代入する
                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

                '月検索 に 日付から月部分を取り出して、集計シートの何列目に有るかMATCH関数で取得して代入する
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

               'セルの値が数値かどうかを判断する
               If IsNumeric(NO検索) Then

                'セルの値が数値かどうかを判断する
                 If IsNumeric(月検索) Then

                    '集計シートの何行目に「NO」があるか・何列目に「月」があるか確認して=クロスするセルに値を足し算する。
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")

                    '集計シートの何3行目〜最終行まで1行ずつ= 最終列のセルにNOの値を足し算する。
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

                 End If
                End If

             'カウントの結果が0と等しいとき(1未満のとき)
             Else

                   '●●&のNOが登録しています。
                   MsgBox 集計.Cells(i, "A").Value & "のNOが登録していません。"

            End If
     Next i

    'A2〜でーたー範囲を取得して、最終列が空欄の時非表示する
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub

(もみじ坂) 2014/11/17(月) 22:18


 こんにちは。

 日本語の説明文だけを通して読まれてはどうでしょう?
 実際の動作(エクセル君の動作です)をイメージしながら...
 イメージが大事です。

 イメージできたら、
 やっていることにモレは無いかダブりは無いか、
 作業の順番に不効率は無いか、
 見つけられるかな、と思います。

 わたしが初心者のころによくしていたのは、
 コードの内容を頭の中で架空のひとに説明すること。
 マクロのことは何も知らないが、地頭のいいひとを想定していました。

( 佳 ) 2014/11/18(火) 07:38


 思い出し。

 コードはこうなっていると考えたら、ついでに
 こうなってなかったらどうなるかな、と考えたりしました。

 「裏返す」というのは、コードを考えるときのテクニックのひとつです。
( 佳 ) 2014/11/18(火) 07:42

 >コードに対しても、メモってたはずなのに、認識違いとかも出てきたりします。
 たぶん、メモり方が悪いと思います。

 当初は
  ○○って書けば出来る様です。どこかで見ました。
 と、コードを書いておられましたよね。

 メモに ××したい時は○○と書けば良い としか書いてなかったら
 「あの人のコードはうまくいってるのに、私のじゃうまくいかない」
 となる可能性が高いです。

 たとえば

    'A2〜データーの範囲を取得して取得して、最終列のフィルターをクリアする
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

 このコードの「'A2〜データーの範囲を取得して」の部分は
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列))
 にあたります。

 もしもメモに
  A2〜データーの範囲を取得する時は、 Range(Cells(2, 1), Cells(NO最終行, 月最終列)) と書けばよい
 とメモっていたとしたら、範囲を取得したいと思った時に
   Range(Cells(2, 1), Cells(NO最終行, 月最終列))
 と書いてしまいませんか?

 具体的には
    Sub ダメな例01()
        Range(Cells(2, 1), Cells(NO最終行, 月最終列)).Select
    End Sub
 こんなコードです。

 これでは、思った範囲は選択できません。

 test11のコードの、該当部分で
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列
    ↓
    集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).Select
 と書き換えた場合は、思った範囲が選択出来ます。

 同じコードでも、OKな時と ダメな時がありますね。
   他の人のコードを見ると○○と書いてあったから、○○と書く
 ではコードを書ける様になるのは難しいと思います。
   コードを見て「○○」と書けばどうしてやりたいことが出来るのかが分かってから「○○」と書く
 の繰り返しが必要だと思います。

 ダメな例01がダメなのは
    'NO最終行 に 入力されているデーターの最終セルの行数を取得し代入する
    '月最終列 に 入力されているデーターの最終列の列数を取得し代入する
 をやってから使える一行なのに、それをせずに最後の一行だけが書かれているからですよね?
 この場合「○○」と言う記述は、一行ではなく 三行セットだったのです。
 三行セットで真似できれば、思った通りの範囲が取得できると思います。

 関連部分なので続けて書きますが
 コードのコメントとして「'A2〜データーの範囲を取得して」と表現してあるのは
 私は正確ではないと思います。

    Range("A1:B5").AutoFilter
 このコードは「A1:B5の範囲を取得してオートフィルタを設定」でしょうか?
 私が言葉にするなら「A1:B5の範囲にオートフィルタを設定」です。

 ですが、もみじ坂さんが同じだと思われるなら【取得】があってもなくても良いと思います。
 今回は、コードがあってそれにコメントを付けていますが
 コードが無い状態で、コメントを見た時に、コードに出来るかどうか が問題です。

 【取得】と言う単語に、引きずられそうになりませんか?

 また、「'A2〜データーの範囲」の「データの範囲」とは具体的にどの範囲ですか?
 曖昧なままではコードに出来ません。
 考える時から、出来るだけ曖昧にならない様に考えてもらうのが良いと思います。
 もちろんここも
  「文字にすると長くなるだけだからしなかったけど A2からどこのセルまでの範囲の事かちゃんとわかってるし
   どうしてそう書けば良いのかの理屈も分かってるよ」
 と言うのであれば、その表現で良いと思います。

 ちなみに
    'NO最終行 に 入力されているデーターの最終セルの行数を取得し代入する
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
 ですが、たとえば A1:A5にオートフィルタを設定して
 絞り込みを行い、A1:A3セルが表示され A4:A5セルが非表示にしてある時
 集計.Cells(Rows.Count, 1).End(xlUp).Row では「3」と言う値が取得されます。
 絞り込みが行われていなければ、「5」です。

 今後、いろいろなコードを作るときに問題になるかもしれませんので
 頭の片隅にでものけておいてもらえたらと思います。

 >>納得されたのであれば、そろそろ変更して下さい。
 > (??) エラー値を検索するのですか? 
 2014/11/14(金) 13:45のもみじ坂さんの投稿ですが 
   >なのに、変数:NO検索 に数値が入っているかどうか確認するのは変ですよね?
   言われてみればそうですね。 ^^;;
 と有りますので、納得されたのかと思っていましたが。。。?
  
(HANA) 2014/11/18(火) 15:12

 >○○って書けば出来る様です。どこかで見ました。
   たしかに、いつもそう書いてるような気がします。

 >と書いてしまいませんか?
   値クリア としか 書いてないです (´ロ`ill)

 >Range(Cells(2, 1), Cells(NO最終行, 月最終列))
   これは最初に間違えたやつですよね
   シート名をしっかりと書くようにと注意された記憶あります。
   ↓ が正しいと
   集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列))

 >1.集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列
 >2.集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).Select

   どちらを書いても過程は少し違いますが。
   欲しい結果にはたどり着くってことですか?
   1. は 一旦 フィルターをクリアして → 計算して 
   2. は フィルターをクリアせずに → でも欲しい結果でた (??)
   .Selectを使ったからですか?
   データー範囲を取得して → 計算して → 取得した範囲で再度フィルターをかける
   というイメージでしょうか?
 

 >と言うのであれば、その表現で良いと思います。
   いえ、説明するポイントがよくわかってないだけです (*゚Å゚;*)
   だから、コード書くときに迷いが生じるんですね。。

 >NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
  ここも問題になるんですか?

  ・この書き方が問題なのか。
  ・考え方が問題なのか。
  ・そういうのだから、ケースバイケースで対象するなのか。  (??)

 >「'A2〜データーの範囲」の「データの範囲」とは具体的にどの範囲ですか?
  A2〜最終行と最終列の範囲 ? 
  下のデーターからすると A2〜I6まで。。。

 [a]	[b]   	[c]	[d]	[e]	[f]	[g]	[h]	[I]
NO	商品名前	個数	名称	1 月	2 月	3 月	4 月	合計
A01				    30 				 30 
A02								
A03						    50 		 50 
A05						    130 		130 

 > と有りますので、納得されたのかと思っていましたが。。。?
  確かに、書きましたが、
  long で数字かどうか調べてますが。
  NO検索 でも数字を調べてますが、
  変だけど、必要だなので、使ってるんですよね?
  NO検索 なくしたら困りますしね。

  もうちょっと考えてみます。
(もみじ坂) 2014/11/20(木) 23:45

 >値クリア としか 書いてないです (´ロ`ill)
 もしかして
  値クリアする時 Range(Cells(3, 5), Cells(NO最終行, 月最終列)).ClearContents
 って書いてありますか?

 書くなら、
  'E3〜A列最終行,2行目最終列 の範囲の値をクリア
    NO最終行 = Cells(Rows.Count, 1).End(xlUp).Row
    月最終列 = Cells(2, Columns.Count).End(xlToLeft).Column
    Range(Cells(3, 5), Cells(NO最終行, 月最終列)).ClearContents
 コード部分は、この3行の記述がセットですね。

 > ↓ が正しいと
 >集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列))
 全部に「集計.」を書くのが正しいのかどうかは ちょっと良くわかりません。
 もしも
  Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列))
 最初の「集計.」をなくしても 集計シートの Cells(2, 1)とCells(NO最終行, 月最終列)の範囲 になります。

 例えば
  集計.Range("A1", "B2")
 と書けば、集計シートの A1とB2の範囲 だから・・・と考えて、単純に
  集計.Range(Cells(1, 1), Cells(2, 2))
 とやったのではエラーになってしまいます。
 『「A1」「B1」の文字列にしてないな』と思って
  集計.Range(Cells(1, 1).Adress, Cells(2, 2).Adress)
 にしたら、エラーになりませんし、目的の範囲です。

 慣れてくれば、必要でない所のシートの指定は無くしてしまっても良いと思います。
 でも、慣れるまでは習慣にしておく方が 間違いが少なくなると思います。

 >どちらを書いても過程は少し違いますが。
 >欲しい結果にはたどり着くってことですか?
 いいえ、二つのコードは別のものです。
 (「集計.」をなくしているのも、現在の状況から少し離れて 汎用的な話をしていると言う意図です。
  アクティブでないシートのセルは、Select出来ませんし。)

 もう一度書きますが
    Sub ダメな例01()
        Range(Cells(2, 1), Cells(NO最終行, 月最終列)).Select
    End Sub
 では、【思った範囲が選択出来ない】と言う例の話です。

 必要な部分を抜き出して
    Sub OKな例01()
        NO最終行 = Cells(Rows.Count, 1).End(xlUp).Row
        月最終列 = Cells(2, Columns.Count).End(xlToLeft).Column
        Range(Cells(2, 1), Cells(NO最終行, 月最終列)).Select
    End Sub
 とすれば、【思った範囲が選択できる】です。
 ・・・・・変数の宣言部分は割愛・・・・・

 実際のコードの
 >集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列
 の所を
  集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).Select
 にしたら(集計シートがアクティブな状態の時)目的の範囲を選択出来ます。
 なぜなら、それより上に
        NO最終行 = Cells(Rows.Count, 1).End(xlUp).Row
        月最終列 = Cells(2, Columns.Count).End(xlToLeft).Column
 があるからです。

 この2行が無い ダメな例01 のコードは ダメなんです。

 オートフィルタの絞り込み云々の話とはまた別の話です。

 >>NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row
 >ここも問題になるんですか?
 今回は、たぶん 問題にならないと思います。
  オートフィルタの範囲は、自動的に拡張される様なので。
   時々、範囲から外れてしまう時があるので どういうご機嫌なのか
   私の操作方法が悪いのか 定かではないのですが。。。
 将来問題になるかもしれないので、思った動きをしないと思った時に
 「そういえば、フィルタリングをして End(xlUp) としたら、表示の最終セルを取得するんだった」
 と、思い出してもらえたら良いと思います。

 具体例が必要ですか?
 すでに、先のコメントで書いている事の繰り返しになりますが。

 >> と有りますので、納得されたのかと思っていましたが。。。?
 > 確かに、書きましたが、
 > long で数字かどうか調べてますが。
 > NO検索 でも数字を調べてますが、
 longで数字かどうか調べてませんし、NO検索で数字(かどうか)は調べてませんよ?

 たとえば、もみじ坂さんが ゴミ箱の番人をしているとします。
 いろんな人が、もみじ坂さんに「このゴミを入れて」ともってきます。
 もみじ坂さんは、本当にそれがゴミかどうかを確認して、ゴミの場合 受け取ってゴミ箱に入れます。
 もしも、ゴミ以外のものを持ってきたら「ゴミじゃないから入れられない」
     でもその場合どうすれば良いか言われていないので困ってしまい、処理が中断する。

 さて、ゴミ箱がいっぱいになったら 今度はゴミ袋に入れ替えます。
 一つずつ入れ替えるのですが、その時一つずつに対して「これってゴミかしら?」と確認しませんよね?
 【本当にそれがゴミかどうかを確認して、ゴミの場合 受け取ってゴミ箱に入れた】のですから
 ゴミ箱の中にはゴミ以外入っていません。

 ゴミ箱にはゴミだけ入れると決める。(ゴミ以外を入れようとしたら処理が中断する。)
   ・・・・Dim NO検索 As Long
 本当にそれがゴミかどうかを確認する
   ・・・・If カウント <> 0 Then
 ゴミ箱に入れる
   ・・・・NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

 今度はゴミ袋に入れ替える時
 一つを取り出して、ゴミかどうか確認する
   ・・・・If IsNumeric(NO検索) Then
 ゴミ袋に入れる
   ・・・・集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")

 と言ったコードになっているのですが、イメージが伝わりますか?

 本当にそれがゴミかどうかを確認して、ゴミの場合 受け取ってゴミ箱に入れたからゴミ箱の中にはゴミ以外入っていません。
 「一つを取り出して、ゴミかどうか確認する」と言う作業をしても 全て「TRUE」になりますし
 作業をしなくても、【確実に】ゴミなのですから、問題ないですよね?
  
(HANA) 2014/11/21(金) 10:14

 こんにちは。

 >  NO検索 でも数字を調べてますが、
 >  変だけど、必要だなので、使ってるんですよね?
 >  NO検索 なくしたら困りますしね。

 だから。
 日本語で考えてみてはどうかと提案したんです。
 難しいことをするときは使い慣れた道具を使うのが吉です。
 たいていのひとはVBAより日本語のほうが得意です。

 ということで、抜粋です。
 >'集計シートにデーターシートと同じ値があるかを調べる
 > 'カウントの結果が0と等しくないとき(1以上のとき)
 >  'NO検索 に Noが集計シートの何行目に有るかMATCH関数で取得して代入する
 >  'セルの値が数値かどうかを判断する 

 これをわたしなりに言い換えると
 '集計シートにデーターシートと同じ値があるとき
  'NO検索 に Noが集計シートの何行目に有るかMATCH関数で取得して代入し
  'それが数値かどうかを判断する
 となりますが、
 集計シートにデーターシートと同じ値があるなら、NO検索は数値になるに決まっています。
 数値でなければエラーが出ています。エラーを出さないためにあらかじめcountif関数で
 チェックしてるのです。

 >  NO検索 なくしたら困りますしね。
 NO検索は必要です。でも、数値かどうかの確認は必要ありません。

( 佳 ) 2014/11/22(土) 11:30


 訂正です。

 >数値でなければエラーが出ています
 とあるのは間違いです。application.matchはエラーにはなりません。エラー値を返します。

( 佳 ) 2014/11/22(土) 11:35


 ちなみに。

 データシートの見出し項目はすべて集計シートに存在することが確実なら
 match関数での確認も必要ありません。

 データシートの見出し項目がすべて集計シートに存在する状態を、マクロで
 作り出したばあいも、もちろんmatch関数での確認は必要ないです。

 いまの方針より こちらの考え方のがシンプルかなと思いますが
 (集計シートのデータの無い行や列を非表示にしなくていいし)
 最初の方針を貫くのも勉強ではあります。

( 佳 ) 2014/11/22(土) 11:46


 たびたびすみませんが、誤解を誘っていてはいけないので
 念のため。

 >集計シートにデーターシートと同じ値があるなら、NO検索は数値になるに決まっています。
 これは間違えていませんので。
 集計シートにデーターシートと同じ値がないなら、NO検索はエラー値になりますが
 集計シートにデーターシートと同じ値があるなら、NO検索はかならず数値です。

( 佳 ) 2014/11/22(土) 11:52


 佳さん。
 さすがにそれは、取り下げてもらえませんか?
 違ったゴールに向かった誘導が同時に行われると
 混乱の元になると思います。
  
(HANA) 2014/11/22(土) 14:10

 (HANA)様

 まずは

 >Sub ダメな例01()
 >        Range(Cells(2, 1), Cells(NO最終行, 月最終列)).Select
 >    End Sub

 こちらの件了解しました。実はこのボケ以前やりました。 (*´-`*)ゞ
 コードの中に 変数 を使ってるのに。
 変数の 中身も 一緒にしないと コードが迷子するんですね。
 下のように変数使わずにしっかりと指令分を書けば問題なく 処理できるんですね。

 Sub これならOK例01()
        Range(Cells(2, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, Cells(2,   Columns.Count).End(xlToLeft).Column)).Select
    End Sub
(もみじ坂) 2014/11/22(土) 23:34

 (HANA)様

 さて本題は

 以前のコードは

 ’[1]数字のみ処理する
 Dim NO検索 As Long

  '[2]NO検索 に Noが集計シートの何行目に有るか見てみる(数行=数字)
  NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

    '[3]数字じゃないと処理しない

        If IsNumeric(NO検索) Then

      ’[4] [3]がOKなもののみ計算する

           集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
        End If

 [1] ここは数字しか入れない。
 [3] 数字かどうか取り出して確認する
 [2] OK数字だよ
 [4] じゃ計算できるね。

だったのが、

 カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))
 を追加することによって、
 ダブった作業が発生したんですね。

 ’[1] 数字のみ処理する
 Dim NO検索 As Long

  '[2] NO検索 に Noが集計シートの何行目に有るか見てみる(数行=数字)
  NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

   '[5] 1以上の数字じゃないと処理しない

      If カウント <> 0 Then

    '[3] 数字じゃないと処理しない

        If IsNumeric(NO検索) Then

      ’[4] [3]がOKなもののみ計算する

           集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")
        End If

 [1] ここは数字しか入れない。
 [5] 数字かどうか取り出して確認する
 [2] OK数字だよ
 [3] ホントに数字かどうか取り出して確認する
 [4] じゃ計算できるね。

すると

 [2] のところで OK でてるのに、
 [3] でもう一回数字かどうかを確認する作業が無意味になるんですね。

そう考えると

 コードこんな感じでしょうか?

 Sub test12()

 ' 整数型             Integer
 ' 長整数型           Long
 ' 日付型       Date
 ' オブジェクト型   Object
 ' 文字列型       String
 ' バリアント型     Variant

    Dim NO検索 As Long, NO最終行 As Long
    Dim 月検索 As Long, 月最終列 As Long
    Dim i As Long
    Dim 行番号 As Long
    Dim 集計 As Worksheet
    Dim データー As Worksheet
    Dim カウント As Long

    '「集計」にSheet5をSetする
    Set 集計 = Worksheets("Sheet5")

    '「データー」にSheet6をSetする
    Set データー = Worksheets("Sheet6")

    'NO最終行 に 入力されているデーターの最終セルの行数を取得し代入する
    NO最終行 = 集計.Cells(Rows.Count, 1).End(xlUp).Row

    '月最終列 に 入力されているデーターの最終列の列数を取得し代入する
    月最終列 = 集計.Cells(2, Columns.Count).End(xlToLeft).Column

    'A2〜データーの範囲にフィルターをクリアする
     集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列

   'E3〜データーの範囲の値をクリアする
    集計.Range(集計.Cells(3, 5), 集計.Cells(NO最終行, 月最終列)).ClearContents

    'For〜Nextは条件により繰り返えして処理をする(3行目から値がある最終行まで)
      For i = 3 To データー.Cells(Rows.Count, 1).End(xlUp).Row

            '集計シートにデーターシートと同じ値があるかを調べる(0=なし、1=1個ある、2以上はダブってる)
             カウント = WorksheetFunction.CountIf(集計.Range("A3:A" & Rows.Count), データー.Cells(i, "E"))

            'カウントの結果が0と等しくないとき(1以上のとき)
            If カウント <> 0 Then

                'NO検索 に Noが集計シートの何行目に有るかMATCH関数で調べて代入する
                NO検索 = Application.Match(データー.Cells(i, "E"), 集計.Range("A:A"), 0)

                '月検索 に 日付から月だけを取り出して、集計シートの何列目に有るかMATCH関数で調べて代入する
                月検索 = Application.Match(Month(データー.Cells(i, "B")), 集計.Range("2:2"), 0)

                    '集計シートの何行目に「NO」があるか・何列目に「月」があるか確認して=クロスするセルに値を足し算する。
                    集計.Cells(NO検索, 月検索) = 集計.Cells(NO検索, 月検索) + データー.Cells(i, "j")

                    '集計シートの何3行目〜最終行まで1行ずつ= 最終列のセルにNOの値を足し算する。
                    集計.Cells(NO検索, 月最終列) = 集計.Cells(NO検索, 月最終列) + データー.Cells(i, "j")

             'カウントの結果が0と等しいとき(1未満のとき)
             Else

                   '●●&のNOが登録しています。
                   MsgBox データー.Cells(i, "E").Value & "のNOが登録していません。"

            End If
     Next i

    'A2〜データー範囲に、最終列が空欄の時非表示する
                集計.Range(集計.Cells(2, 1), 集計.Cells(NO最終行, 月最終列)).AutoFilter Field:=月最終列, Criteria1:="<>"

 End Sub

 ※2014/11/23(日) 21:09 修正版

(もみじ坂) 2014/11/23(日) 00:09


 ( 佳 )様
 ありがとうございます。
 同じことあやるにも、さまざまなやり方や、考え方があることを
 大変参考になりました。

 >データシートの見出し項目がすべて集計シートに存在する状態を、マクロで
 > 作り出したばあいも、もちろんmatch関数での確認は必要ないです。
 確かにそうですね。データーシートのダブらない項目を集計シートに転記させてから計算すれば,
 シンプルになると思いますが、前回 ( 佳 )様 のコメントで、
 HANA様の 方針にこのまま進もうと思います。 コードを理解できれば、変更はさほど難しくはないと思います。

 もう少し頑張らせてください 柱|皿 ̄)q

 ただ、見てる方はイライラするレスになってると思いますが
 (私の理解度が低いせいで。なにせ、4回読んでようやく理解したぐらいですから −x−)、
 長い目で暖かく見守っていただけると幸いです (*´-`*)ゞ ポリポリ
(もみじ坂) 2014/11/23(日) 00:24

 あれ?
  test12のコードだと、エラーになりますよ?
  
(HANA) 2014/11/23(日) 19:09

 (。´・ω・)ん?
 問題なく、正しく計算されましたよ。

 コピーした時にトラブル発生したのかしら?

 コードを修正しました。

(もみじ坂) 2014/11/23(日) 21:11


 test12はそれで良いです。
  説明の方のコードの順番だけがおかしいのかな。。。?

 >[2] のところで OK でてるのに、
 >[3] でもう一回数字かどうかを確認する作業が無意味になるんですね。
 そうなんです。
 今回は、先に Variant で「エラー値でもなんでも一旦結果を入れる」としたので
 [3]を入れたコードが完成して、そのあと Long で「数値だけ入る様にCOUNTIF関数で先に確認する」
 を追加したので、[3]が残ってしまいました。

 方針が途中で変わると、こんな箇所が出てきたりしますので
 出来るだけ、方針を詳細に決めてから コードの作成に取り掛かるのが良いと思います。

 さて、次に「番号が入力された場合」もやりましょうか。
 test12から、日本語の部分を書き出して それに条件を追加してみて下さい。

 コードを考えるのは まだ後ですよ。
    
(HANA) 2014/11/23(日) 22:02

 書き忘れてました。
 スレが長くなったので、この辺で新しくしてもらえたらと思います。
  
(HANA) 2014/11/23(日) 22:48

[[20141124231425]]『マクロで合計 4』 へ
(もみじ坂) 2015/03/08(日) 23:09

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.