[[20100315185515]] 『マクロを体裁よく書く方法は?』(?) ページの最後に飛ぶ

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

 

『マクロを体裁よく書く方法は?』(?)
 Excel2003/WindowsXP

 マクロデータを確認したら、長いマクロデータがありました。そこで、
前回ご教授いただいたことを参考に、修正してみましたがエラーが出ます。
どこが間違っているか教えてください。

 各シートは次のような構成になっています。

 1.シート1(履歴)
    A   B    C    D        E    F   G
 1 日付	TEST	社名	品名	部品名	図番 発注先
 2
 3

 2.シート2(集計欄(月))
    A  B   C    D   E     F    G  H    I     G
 1     1月度         日付	TEST	社名  品名 部品名	 図番 発注先  
 2     項目   件数           ・                       
 3 A   ・  ・            ・
 4 B   ・  ・            ・          
 5 C   ・  ・            ・
 6 D
 7 E
 8

 3.シート3
     A      B     C     D  ・ ・ ・  
 1         6月   7月  8月
 2 項目1
 3 項目2
 4 項目3
 5 項目4
 6 項目5

 作成したマクロコードは

 Private Sub CommandButton1_Click()
Dim 行 As Long, 列 As String
    検索開始日 = ">=" & UserForm2.TextBox1.Text
    検索終了日 = "<=" & UserForm2.TextBox2.Text
    Sheets("集計欄(月)").Select
    Range("D1:G150").Select
    Selection.ClearContents
    Sheets("履歴").Select
    Range("A1").Select
    Selection.AutoFilter
    Selection.AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日
      上 = 6
        左 = 1
        下 = Range(Cells(上, 左), Cells(上, 左)).End(xlDown).Row
        右 = 10
    Range(Cells(上, 左), Cells(下, 右)).Select
    Selection.Copy
    Sheets("集計欄(月)").Select
    Range("J4").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    Range("J3").Select
    Sheets("履歴").Select
    Selection.AutoFilter
    Range("A3").Select
    Sheets("集計欄(月)").Select

    If Range("c3").Value <= 5 Then
        列 = Range("c3").Value + 8
    Else
        列 = Range("c3").Value - 4
    End If

    Sheets("集計欄(まとめ)").Range(列).Value = Range("a5:a9").Value
End Sub

 です。マクロを実行すると、Sheets("集計欄(まとめ)").Range(列).Value = Range("a5:a9").Valueにエラーマークが表示されます。

 上記マクロコードのセル位置とシートのセル位置が一致しないところがありますが
シートはそのまま表示できないので修正しています。マクロコードのセル位置まで
修正するのは面倒なのでそのまま貼り付けました。(?) 

    


 「Range(列)」はどのようなセル範囲を取得したくてこのように書いていますか?
列 = Range("c3").Value + 8
列 = Range("c3").Value - 4
では、"13"とか"6"という「半角の文字列数字」が変数[列]に取得されますが、
Range("13").Select という書き方ではSelectできませんよね。
レイアウトを見る限りではしーと3?の「2行目の[列]列目」に"集計欄(月)"の
A5:A9を貼り付けたいようですが。
変数[列]をString型ではなく、Long型で宣言して、Cells(2,列)のような書き方
かしら?
ただ例の表では、Sheets("集計欄(月)").Range("c3")には「件数」となっている
し、Sheets("集計欄(月)").Range("a5:a9")もなぜ、そんな中途半端なところから?
って感じだし・・・。
 
ああ、なるほど。
>マクロコードのセル位置まで
>修正するのは面倒なのでそのまま貼り付けました。
自分の面倒は厭うけど、回答者をこう言うことで悩ませて時間使わせるのは厭わな
いし、気にならないと、宣言してありましたね。失礼しました。
では、ごきげんよう。
(みやほりん)(-_∂)b

 みやほりんさん手抜きの質問ですみませんでした。
 再度サンプルシートにあわせた、マクロコードを書き直しました。

 1.シート1(履歴)
    A   B    C    D        E    F   G
 1 日付	TEST	社名	品名	部品名	図番 発注先
 2
 3

 2.シート2(集計欄(月))
    A  B   C    D   E     F    G  H    I     J
 1      1  月度    日付	TEST	社名  品名 部品名	 図番 発注先  
 2     項目   件数           ・                       
 3 A   ・  ・            ・
 4 B   ・  ・            ・          
 5 C   ・  ・            ・
 6 D
 7 E
 8

 3.シート3
     A      B     C     D  ・ ・ ・  
 1         6月   7月  8月
 2 項目1
 3 項目2
 4 項目3
 5 項目4
 6 項目5

 Private Sub CommandButton1_Click()
Dim 行 As Long, 列 As String
    検索開始日 = ">=" & UserForm2.TextBox1.Text
    検索終了日 = "<=" & UserForm2.TextBox2.Text
    Sheets("集計欄(月)").Select
    Range("D1:G150").Select
    Selection.ClearContents
    Sheets("履歴").Select
    Range("A1").Select
    Selection.AutoFilter
    Selection.AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日
      上 = 6
        左 = 1
        下 = Range(Cells(上, 左), Cells(上, 左)).End(xlDown).Row
        右 = 10
    Range(Cells(上, 左), Cells(下, 右)).Select
    Selection.Copy
    Sheets("集計欄(月)").Select
    Range("D3").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    Sheets("履歴").Select
    Selection.AutoFilter
    Sheets("集計欄(月)").Select

    If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If

    Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Value
End Sub

 このマクロの流れは月初に前月の履歴データを検索しそれを集計欄(月)"D2"以下に貼り付け
E列のテストには5種類あるのでこれを関数を使用して、C列件数にまとめています。
これを集計欄(まとめ)の対応月に貼り付けたいのです。現状はIFを使用してマクロコードを
作成していますので、非常に長い物になっています。(?)


 エラーになったときの「列」の値はどうなっていますか。
 (semm)


 エラー表示が「アプリケーション定義またはオブジェクト定義のエラーです。」となり、
 Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Valuenにイエローマークが
付き、列の値は解りません。(?)


 マウスで矢印を列に重ねると値が表示されます。
 それはさておき、質問を変えます。
 Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Value
 これはどのような動作をさせるために書いたものですか。
 またこの時の想定している列の具体的な値は何ですか。
 (semm)

 シート2(集計欄(月))のC3からC7までのデータをB1の月数にあわせてシート3
(集計欄(まとめ)(サンプルしーとにこのシート名を表示していませんでした))の
1行の同月の月を検索しその列の2〜6行に転記したいのです。
 具体的なデータは数値です(3件とか10件とか(実際は件をいれず数値だけです。)。

 「列」の値の件ですが、どのシートのどの「列」を選択すればいいのでしょうか。
それともどのシートのどの「列」を選択してもいいのでしょうか。(?)

 シート2(集計欄(月))のB1は 1 ですから
    If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If
 の結果、「列」は Range("B1").Value + 8 ⇒ "9" (「列」は文字列型変数ですので文字列です。)
 すると、Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Value は
 Sheets("集計欄(まとめ)").Range("9").Value = Range("C3:C7").Value となります。
 Sheets("集計欄(まとめ)").Range("9")はどのセル(または範囲)のことだと思いますか。
 (semm)


 集計欄(まとめ)シートのI2〜I6の範囲です。

 本日エラー表示の件で「アプリケーション定義」をネットで検索確認していてたところ、
セルのデータに関数(=)が入っている場合はこのことをマクロコードにも入れている書き込みが
ありました。2回目の説明に入れていますように、集計欄(月)のC3〜C7は関数を使用してまとめた
数値です。このこともエラーの出る原因の一つになっていないでしょうか。(?)

 それはあなたが、その範囲になって欲しいと思っているだけではないですか?
 それでは
 Sheets("集計欄(まとめ)").Range("10.5")
 Sheets("集計欄(まとめ)").Range("100")
 Sheets("集計欄(まとめ)").Range("-10")
 ならどの範囲ですか。
 エクセルにはRange("9")なんて範囲は分からないから出ているエラーです。
 (semm)

 解りません。

 でも以前、次のようにこのコーナーで教えてもらい
 If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If

 と指示することにより、正常に作動いたしました。(列は行でしたが。)(?)

[[20100312203656]] 『マクロを体裁よく書く方法は?』(?)
 以前のはこれですね。コードをよく見てください。
 元のコードでは「列 & 行」となっていて、列と行の両方を指定しています。
 (semm)

 じゃ、以前指導いただいたこのコードを参考にして実行するためには、行も指定
しなけ れば、ならないのですね。考えて見ます。予感的にですがまた長いコードに
なりそう ですが。それと、今までの、ご指導から判断して、現状のコードでも
間違いを正せ ば、作成できそうですが、かなり高度なコードのようです。
マクロの入門者では、ちょっと難しいようです。(?)


 列は(文字列になっていますが)算出できています。
 行は先頭は2行目です。
 Range(列 & 行) は 列も数値にして Cells(行, 列) と出来ます。
 (semm)


 Sheets("集計欄(まとめ)").Range(列 & 行).Value = Range("C3:C7").Valueをご指導のように
Sheets("集計欄(まとめ)").Cells(2, 列).Value = Range("C3:C7").Value として実行してみました。

 エラーは出なくなりましたが、シート3集計欄(まとめ)の選択月の項目1にしかデータは
貼りつきませんでした。本当はシート2C3:C7ノデータをシート3の選択月に5項目とも同時
に貼り付けたいのですが。

 それとCells(2, 列).Value とすることによりエラーが出なくなった、意味がいまいち
はっきりと理解できていません。(?)

 5項目すべてに貼り付けるマクロは
 With Sheets("集計欄(まとめ)")
 .Cells(2, 列).Value = Range("C3").Value
 .Cells(3, 列).Value = Range("C4").Value 
 .Cells(4, 列).Value = Range("C5").Value 
 .Cells(5, 列).Value = Range("C6").Value 
 .Cells(6, 列).Value = Range("C7").Value
 End With
 としたところ、思いどうりの作動をしました。

 ただCells(2, 列).Value とすることによりエラーが出なくなった、意味がいまいち
はっきりと理解できていません。それと上記7行を1行にまとめられませんか。

 (?)仕事中

  
  

 Sheets("集計欄(まとめ)").Cells(2, 列).Resize(5).Value = Range("C3:C7").Value

 1月はI列ですので、これでもエラーは出なくなると思います。
 Dim 行 As Long, 列 As String
 列 = "I"
 行 = 2
 Sheets("集計欄(まとめ)").Range(列 & 行).Value = Range("C3:C7").Value
 やはり項目1だけですが。
 月によって"B"・・・"M"を「列」に代入すればOKです。
 (semm)


 横から済みません。
 変数の中身がご自身で確認出来ないのは
 まず致命的なことだと思いますので。。。。
 取り敢えず、ローカルウィンドウを表示させて下さい。
   VBEのメニュー・表示(V)→ローカルウィンドウ(S)

 次に、コードの左側に灰色の部分が有ると思いますが
 クリックすると 茶色い●が表示されます。
  (もう一度クリックすると、消えます。)
 マクロが実行されたときに、これが付いている行で実行が一旦ストップします。

 現在作って居られるコードの先頭の方に ● をつけて
 マクロを実行すると、その行が黄色くなり、一旦ストップしますので
 [F8]キーをおして、一行ずつ進めてみて下さい。

 その時、それぞれの変数の値をローカルウィンドウで確認してみてもらうと
 良いのではないかと思います。

 (HANA)

 semmさん私の初歩的な質問に根気よく答えてくださり非常に有難うございました。感謝いたします。
それぞれの回答でマクロの流れについてはある程度理解できるので、考え付くコードを書いて
来ましたが、なにせマクロのテクニックにおいてはど素人なもので、皆さんからしてみれば
全くトンチンカンなコードだったと思います。しかし、皆さんのご指導のおかげで曲りなりに
正常に作動するマクロコードを書くことができました。

 そこでsemmさん、もう一つ質問させてください。やはり先の7行は1行にすることはできないの
でしょうか。もし先の説明がそのための説明であれば理解できておりません。ゴメンナサイ。

 HANAさんグットタイミングに適切なアドバイスを有難うございます。早速行って見ました。
値の意味が少しは理解(すべてではなくてごめん)できましたが、この中で一つ疑問に思ったことが
あるので質問いたします。行の値が数値ではなく、""になっているのは、先の5行を代表して
""となっているのかそれともほかの意味があるのでしょうか。

 (?)

 >値の意味が少しは理解(すべてではなくてごめん)できましたが
 でしたら、前回
  「列」の変数に D,B,C等の列をあらわす【文字列】が入り
  「行」の変数に 4〜15 の行をあらわす【値】
 が入っていたのも分かりましたか?
 また、例えば 「列」の変数に Dが入っていて、「行」の変数に 10 が入っていた場合
 列 & 行 とすると、→ "D" & 10 = "D10" と言う
 セル番地をあらわす文字列になると言う事も イメージがわきますか?

 >行の値が数値ではなく、""になっているのは・・・
 良い所に気付いて頂けました。
 これの疑問への回答は、既にsemmさんが書いて居られるのですが
 一寸イメージをふくらませてみてください。

 ワークシート関数を使うときでも、"" を付けることが有りますね。
 例えば、=IF(A1=1,"○","×") と言った感じで【文字列】をあらわす時に
 前後を「""」で囲います。
 =IF(A1=1,"1","2")の様に、数字も「""」で囲えます。
 セルには「1」や「2」が表示されますが、
 =IF(A1=1,1,2)の式の結果表示されている「1」や「2」とは
 性質の異なる「1」や「2」になりますね。
  例えば、=SUM(セル範囲)で合計出来ない物と、出来る物。

 前者は「"1"」「"2"」と言う【文字列】で、後者は「1」「2」と言う【値】 です。

 前回のコードを少し改造して、こんなコードで確認してみて下さい。
    Sub Test()
    Dim 行 As Long, 列 As String
        行 = 5
        列 = 5
    End Sub
 行は「5」のままですが、列は「"5"」と成りますね?
 二つの違いは、Dim □□ As ◇◇ の「◇◇」部分が、
 Long に成っているか、String に成っているかしかありません。

 このDim〜の部分は、変数の宣言をしている所です。
 エクセルに「今からこの名前の変数を使うからね」と申し出ます。
   これが Dim □□ の部分にあたります。
 その時に、一緒に用途も書いておきます。
   これが、その後に続く As ◇◇ の部分になります。

 変数の型(◇◇の種類)に付いては、決まり事なので
 詳しくは調べてみてください。
 今回の二つに付いて簡単に書くと
 Long ・・・値  String・・・文字列 ですので
  Dim 行 As Long = 「行」と言う変数を使います。これには値を入れます。
     ,列 As String =「列」と言う変数を使います。これには文字列を入れます。
 と、言っている事になります。

 すると、コードを作る時に、本当は 列 = "D" と書くつもりだったのに
 間違って 行 = "D" と書いてしまっていた場合
 エクセルが「行には値を入れるんでしょ?"D"って文字列だよ。間違いでしょ?」
 と教えてくれます。

 今回の場合、 列 = 5 と書いてあるので
 「列は、文字列を入れるんだよね。だから"5"ってしておけば良いんだよね」
 と、入れようとした「5」を 文字列になおして入れてくれています。

   semmさんが書いて居られる
   >・・・・・・・
   >の結果、「列」は Range("B1").Value + 8 ⇒ "9" 
   >(「列」は文字列型変数ですので文字列です。)
   の部分の事です。

 前回は、D,B,C等の列をあらわす【文字列】を入れる予定だったので
 変数の型をString としていましたが
 今回は、値として入っていればよいので
 変数の型を Long にしておかれるのが良いと思います。

 ◆◇◆
 それから、変数のお話ついでにもう一つ。。。

 モジュールの先頭に
   Option Explicit
 を入れておくと、宣言していない変数が使えなく成ります。
 いちいち宣言をしないと使えないので面倒ですが
 例えば「Dim 列 As Long」だけが書いてある時に
 本当は 列 = 5 と書くつもりだったのに
 間違って 行 = 5 と書いてしまっていた場合
 エクセルが「行なんて変数使うって言ってないよね?間違いでしょ?」
 と教えてくれます。

 変数の型(As ◇◇ の部分)はいくつかあって、どれを選べば良いのか
 最初は判断が難しいかもしれませんが、せめてDim □□ だけは
 書く習慣を付けておかれるのが良いと思いますよ。
  勿論、変数の宣言を強制にして。
 後ろの As ◇◇ が書いてない場合、Variant と言う型が
 省略されているとしてコードが動きます。

 (HANA)


 HANAさん再々のアドバイス有難うございます。
 確認です。
 Long ・・・値  String・・・文字列
 「値」(Long)とは A、今日とか123であり 「文字列」(String)とは"A"、"今日"とか"123"
という解釈でいいのでしょうか?

 今まで「文字列」の「列」という言葉に私が惑わされていた部分もあります。"A","B","C"は
「文字」であり、「文字列」ではないという勝手な解釈をしていました。(?)


 変数名が「列」で、それに入れるデータが「文字列」で
 入れたデータの意味が「列数」ですから
 紛らわしいですね。

 「文字」と「文字列」は同じ物だと思って下さい。

 「値」と言うのは「数値」の事です。
 足したり、引いたり、掛けたり、割ったり 出来ます。
  1+2 は計算出来ますが、今日(と言う文字)+昨日(と言う文字)は計算出来ませんね?

 タブン、紛らわしいのは 今日(と言う変数に入った値)+昨日(と言う変数に入った値)
 は計算できます。

 正確には Long は -2,147,483,648〜2,147,483,647の範囲の整数 です。
    なので、 Long と書いた変数に 1.5 の様な小数の値を入れると
    勝手に丸めてくれてしまうので、注意が必要です。

 A,B,C,Dの様なアルファベットや、今日 の様な日本語や漢字は
 文字(文字列)です。
 Long の型の変数には入れられません。

 エクセルは融通を利かしてくれるので
 「エラーが出ないからOK」とは言えませんが
 エラーが出るのは駄目です。

 まず、変数の宣言を強制せずに
   Sub Test2()
       Dim 値 As Long
       値 = 今日
   End sub
 こんなコードを実行すると、エラーは出ません。
 でも、ローカルウィンドウを見ると「値」と言う変数と「今日」と言う変数が
 二つ使われている事になっていますね?

 上に変数の宣言を強制する一文を加えて
   Option Explicit '変数の宣言を強制
   Sub Test2()
       Dim 値 As Long
       値 = 今日
   End sub
 とすると、「変数が定義されていません」とコンパイルエラーが出ます。

 「今日」は変数のつもりだったのではなく、文字のつもりだったのなら
 値 = "今日" と変えてみます。
   Sub Test3()
       Dim 値 As Long
       値 = "今日"
   End sub
 ると、「型が一致しません」と実行時エラーが出ますね。

 1 と "1" の違いは、簡単なイメージの言葉を使うと
 数値と数字の違い と言った感じです。

 セルに 001 と入力すると、勝手に 1 と言う数値(値)に変換されてしまいますね?
 でも、最初に「'」を付けて入力すると 001 と言う文字(数字)のまま入力出来ます。
  入力前にセルの書式設定で表示形式を文字列にして於いた時と同じ感じです。
 実際に、セルに 001 と入力したい様な場面を想像すると おそらく
 そのセルのデータは、計算に使うような物ではなく
 ID番号や、名前の変わりに成る様な物だと思います。

 「Long は -2,147,483,648〜2,147,483,647の範囲の整数」と書いてあると
 >「値」(Long)とは A、今日とか123
 と言う解釈のイメージと一致するかどうか、判断出来ますか?

 私は 123 が値であるとは思いますが A,今日 は文字だと思いますし
 全角で書いてある123も ひょっとすると文字かもしれないと思います。
 ただ、A,今日 等が変数の名前として書かれた物で有れば
 その変数に入っている物によって、値かもしれません。

 > 「値」(Long)とは A、今日とか123であり 「文字列」(String)とは"A"、"今日"とか"123"
 >という解釈でいいのでしょうか?
 と言う御質問は、(?)さんが持って居られるイメージが
 私には良く分からないので、何とも言い難い所です。

 どの様な解釈をして居られるのか、もう少し例を挙げて
 説明してみてもらえると良いのですが。

 (HANA) 

 横から失礼します。

 通常の日本語では「値」といったら、5や"5"はもちろんのこと、#DIV/0!のようなエラー値も含まれます。
 場合によっては、ブックやシートや あるいはエクセルそのものを「値」と表現することもあります。

 ただ、HANAさんのおっしゃっている「値」は数値のことですね。
 Long型は数値、それも整数のみを受け入れます。

 > 今まで「文字列」の「列」という言葉に私が惑わされていた部分もあります。"A","B","C"は
 > 「文字」であり、「文字列」ではないという勝手な解釈をしていました。 
 こちらも、通常の日本語の感覚としてはけっして悪くないと思います。
 でも、="" を「長さ0の文字列」と言うように
 エクセルででてくる言葉は、見た目が普通でも「意味も普通とは限らない」のです。

 −佳−

 HANAさん、桂さん有難うございます。
 相談内容が具体的なマクロコードについてではなくなってしまい申し訳ありません。
 しかし、理解を深めるためもう少しこのことについて質問させていただきます。

 「値」と「文字列」の差はその使用しているときの意味内容であって、表現の仕方で区別されると
いうことではないのですね。たとえば、今日が20日(20)を意味して使用しているのであれば
「値」であり、昨日、今日、明日の内の今日を意味しているのであれば、「文字列」ということに
なるのですね。今までの説明では、表現の仕方で区別されているととらえました。" "で
囲われているものが「文字列」、それ以外は「値」と言う捉え方をしていました。

 確認になりますが、それからすると、私が最初に書いているマクロコードの
 Dim 行 As Long, 列 As String
  列 = Range("B1").Value + 8
 の定義のLongとStringは定義の仕方が全く逆になっているということですね。(何度か、
ご説明の中で指摘があったと思いますが、今この意味ががはっきり解りました。) (?)

 ばかばかしいですが、基本は小学校でやったドリルです。
例えば、セルB1が1のとき、
Sheets("集計欄(まとめ)").Range(  ).Value = Range("C3:C7").Value
                ^^^^^^
    変数を使わないでこの部分 ↑ をちゃんと埋めることができるかどうか?
あるいは、他の何種類かの書き方ができるかどうか?
2のときはどうか、12のときはどうか・・・それができて、初めて自分で変数に
置き換えてやってみることができると思うのです。
「それができたら質問なぞしない」と逆ギレされたことは何回かありますが。
でも、学校というのは、答えを教えてくれるところではなくて、
学習の仕方と習慣を身に付けるところだというのが、私の定義なので・・・。
 
さて、
変数は手段。目的のコードをどのように書くか、がしっかり決定することで、
変数の型が決まる、という性質のものです。
>定義の仕方が全く逆になっている
ということではなくて、
「Range(  ) の括弧の中身はこのように書くべきである。だから、
この部分で使用する変数のデータ型は??型が適当である」という思考経路に
ならなくてはなりません。
 
今回の問題の本質は、(?)さんが Range(  ) の括弧の中身を何種類かの方法で
記述するスキルを身につけるべきである、ということだと思ってください。
この点を理解しないと、変数について論議しても、誤解したまま終わります。
 
(みやほりん)(-_∂)b

             


 こんにちは。佳です。

 Long型は「数値」です。ややこしいなら「値」のことは忘れたほうがいいです。
 Long型は「数値」です。整数です。
 何度でも言います。Long型は「数値」です。

 Dim 行 As Long は問題ありません。
 行番号は 1,2,3,4.... 整数ですから。

 問題は列のほうです。
 Dim 列 As String と書いて、たとえば 列 = "A" としたなら
 Range(列 & 1) は Range("A" & 1) であり、Range("A1")のことです。
 ところが、もし、
 Dim 列 As String と書いて、たとえば 列 = "1" としたなら
 Range(列 & 1) は Range("1" & 1) であり、そんなセルは存在しません。
 列 = Range("B1").Value + 8 でも事情は同じです。

 もしも「列 = Range("B1").Value + 8」を生かしたい場合は、
 Dim 行 As Long , 列 as Long と両方ともLong型(整数)で宣言して
 行 = 2
 列 = Range("B1").Value + 8
 Cells(行,列).Select
 というふうにします。


 みやほりんさん、佳さん早速のご返答有難うございます。
 今、昔購入したマクロの基礎の参考書を読み返しています。当時チンプンカンプンだった内容が
皆様がたのご指導で、その内容がすんなりと、頭に入るようになりました。

 そこで、上記に関連したことでもう一つ質問いたします。
 以前
 列 = Range("B1").Value + 8 = "9"
 と教わりました。
 これはサンプルシート2"B1"の数値が"1"だから、変数"行"の答えが"9"になるので
あって"B1"の数値が"3"のときは"11"と変わるのですよね。これが間違いであると
また、私の頭の中は混乱が始まります。

  If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If

 の記述がありますから。(?)今日1日マクロ漬けになります。


 私なりの部分的なサンプルを提示します。
 
Dim 列 As Long
列 = Month(DateSerial(2010, Sheets("集計欄(月)").Range("B1").Value - 5, 1)) + 1
With Sheets("集計欄(まとめ)")
    .Range(.Cells(2 , 列) , .Cells(6 , 列)).Value = Sheets("集計欄(月)").Range("C3:C7").Value
End With
 
「.Cells(2 , 列) 」での[列] の部分はは整数型の数値である必要があるので、
変数[列]は整数型で宣言します。
 
>もう一つ質問いたします。
質問の内容が判然としませんが、変数[列]がどんなデータ型で宣言されているかによって、
その格納内容が異なります。
Range("B1")が 3 のときは、Range("B1").Value + 8 の部分は 11 と計算されますが、
変数[列] が整数型の場合は 数値 11
変数[列] が文字列型の場合は 文字列 "11"
変数[列] が日付型の場合は 1900/1/10 のリテラル値が格納されます。
 
私の素直な(そしてたぶん厳しく聞こえる)感想ですが、
いきなり大物に挑戦しすぎじゃないんでしょうか。
いったんこのユーザーフォームから離れて、標準モジュールのレベルで
自分の思った位置へデータを転記する、というコードを自力で書く、
というところから始めてはいかがですか?
あと、デバッグのスキルもしっかり身に付けるべき。
根がしっかり張っていない木にいくら大きい実を生らせても、木が倒れてしまうだけです。
 
(みやほりん)(-_∂)b

 (みやほりん)(-_∂)bさんご指導有難うございます。
 今日は少々疲れました。VBAの参考書基礎編を半分読み進みました。(みやほりん)(-_∂)bさん
はじめご指導いただいた皆様方のおかげで、すんなりと読み進めました。

 根を張らせるため、初歩から勉強しています。しかし、私にとっては、不明ななことを質問すること
は間違いではないと思います。そのままほっておくほうがよくないことと思い質問しています。

 (みやほりん)(-_∂)bさんの、私の質問に対するお答えは、今までの流れを読まず、このスレ(?)
だけで判断してお答えされているようです。そのため私の質問していることに対しずれているようで
あまり理解できません。失礼なことを言ってすみません。

 再度質問です。
  以前
 Dim 行 As Long, 列 As Long
 列 = Range("B1").Value + 8 = "9"
 と教わりました。
 これはサンプルシート2"B1"の数値が"1"だから、変数"行"の答えが"9"になるので
あって"B1"の数値が"3"のときは"11"と変わるのですよね。これが間違いであると
また、私の頭の中は混乱が始まります。

  If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If

 の記述がありますから。(?)今日1日マクロ漬けでした。


 列 As Long とするのを理解されたのでしたら、正解です。
 ただし、「変数"行"の答えが"9"になるので」は間違いで、列が9になります。
 そして、
 ?さんが書いていた「 Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Value」
 の部分もみやほりんさんが書いた↓に変更する というのが、元々の質問の答えの1つです。
 (他にもいろんな書き方がありますけど、たぶん、参考書に書いてあると思います) 
   (Hatch)
With Sheets("集計欄(まとめ)")
    .Range(.Cells(2 , 列) , .Cells(6 , 列)).Value = Sheets("集計欄(月)").Range("C3:C7").Value
End With

 一寸関係ない話から始まりますが、上で私は
    Sub Test()
    Dim 行 As Long, 列 As String
        行 = 5
        列 = 5
    End Sub
 のコードを載せました。
 ステップインで実行して、行,列 の変数の値を確認して頂けましたか?
 行は「5」のままですが、列は「"5"」と成りましたね?

 そこで、(?)さんに質問を書いてみます。
  Q1.以下のコード
          行 = 5
          列 = 5
     を実行すると、行,列の変数の値はどうなりますか?
  A.行も列も「5」
 と答えますか?

 でも、実際は Test のマクロを実行するので
 行は「5」列は「"5"」ですね?

 ですから、この2行だけではどうなるか実際の所は分かりません。
  変数の型が宣言されているのか、居ないのか。
  されている場合は、何の型で宣言されているのか。
 この情報が有った時に、正確な所が分かります。

 みやほりんさんが書いて居られる↓は
  >変数[列] が整数型の場合は 数値 11
  >変数[列] が文字列型の場合は 文字列 "11"
  >変数[列] が日付型の場合は 1900/1/10 のリテラル値が格納されます。
「変数の型に依って、結果は異なってくる。
 変数の型がどうなっているか、説明がないから分からない。
 整数型ですか?文字列型ですか?日付型ですか?」
 と変数の型に対する理解の確認と質問も兼ねて
 (?)さんの質問への答えが書いてあります。

 Hatchさんからのコメントが有りますが、私としては
 ステップインで実行して、変数の値をご自身で確認してみてもらいたいです。
 すると、質問文も変わってくると思います。
  ○○と考えて、××に成ると思ったが、△△に成るのは何故か。
  △△に成るのは、○○だからだと思うが、それで間違っていないか。

 そして、その時は Sub □□() 〜 End Sub の様に
 動かしてみたのと同じコードを載せてもらうのが良いと思います。
  (こちらでも同じコードで確認が出来ますので。
   不要部分の無いサンプルコードにしてもらうのが良いとは思いますが。)

 (HANA)

 >VBAの参考書基礎編を半分読み進みました。
やばいです。
少しの項目を一週間、繰り返しやり続けたほうが身に付きます。
 
さて、質問、というより、認識の確認という雰囲気ですが、
単純な回答としては、「その認識で、おおむね合っています」
で、根本的なところで、「これが間違いであると」と不安になっているのは、
自身で「間違いない」ことを「体感」していないからだと推測できます。
 
 Sub Test()
 Dim 列 As Long, i As Long
 For i = 1 To 12
 Sheets("集計欄(月)").Range("B1").Value = i
 If Sheets("集計欄(月)").Range("B1").Value <= 5 Then
     列 = Sheets("集計欄(月)").Range("B1").Value + 8
 Else
     列 = Sheets("集計欄(月)").Range("B1").Value - 4
 End If
 Next i
 End Sub
 
上記コードを標準モジュールへ貼り付けてください。
VBEのコマンドメニューで 表示>ローカルウィンドウを開きます。
F8キーを押すと一行ずつコードが実行されます。
ローカルウィンドウには変数[列][i]の状態が表示されます。
繰り返しF8キーを押して、End Subまで実行させて、
変数[列][i]がどのように変化していくのか、ご自身で確認してください。
非常につまらない作業ですが、少なくとも自分の書いているコードを「体感」できます。
 
念のため、
    'Dim 列 As Long
    Sheets("集計欄(月)").Select
    If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 8
    Else
        列 = Range("B1").Value - 4
    End If
    Sheets("集計欄(まとめ)").Range(列).Value = Range("C3:C7").Value
 
この部分の改善案として下記のコードを提案しています。
    'Dim 列 As Long
    列 = Month(DateSerial(2010, Sheets("集計欄(月)").Range("B1").Value - 5, 1)) + 1
    With Sheets("集計欄(まとめ)")
        .Range(.Cells(2 , 列) , .Cells(6 , 列)).Value = Sheets("集計欄(月)").Range("C3:C7").Value
    End With
 
(みやほりん)(-_∂)b

 なんで、小難しい計算↓を持ち出すのか、不可解です。
 「列 = Month(DateSerial(2010, Sheets("集計欄(月)").Range("B1").Value - 5, 1)) + 1」
 なおさら混乱されそうな気がします。

 セル範囲の書き方がわからないのが、大本だと私は思っていたのですが。
 私がちょっとずれているようですので、以降このスレはROMに徹したいと思います。
 失礼しました。 (Hatch)

 こんにちは。佳です。

 なんとなく、?さんは数字と数値の違いをご存じないかな、と感じました。
 そのため変数のはなしがぎくしゃくするのでは、と。

 数値とは、数そのものです。
 たとえば、電線にすずめが三羽とまっていました。そこへ二羽飛んできました。
 すずめは全部で何羽になったでしょう。というとき、あたまの中で 3 + 2 = 5 と考えますが
 この 2 や 3 や 5 が数値です。数値は計算の対象になります。

 数字は、文字です。
 たとえば "奈良" という文字は、文字です。VBAでは文字は""で括るのでしたね。
 同様に "壱阡弐陌参拾円也" という文字は、文字です。
 そして "1230" も文字です。半角にして "1230" も文字です。 
 文字は計算の対象になりません。"奈良"に"埼玉"をかけ算せよと言われても不可能でしょう。

 だから。
 > Dim 行 As Long, 列 As Long
 >  列 = Range("B1").Value + 8 = "9"
 1 + 8 = 9 のつもりでしょうが、この"9"は とても気持ちが悪いです。
 Long型(数値)なのに なぜ "9" かと。
 分かりますか?

 佳さん有難うございます。

 今までのやり取りの中で、マクロに置ける「数値」と「文字」の違いがはっきり理解できました。
さらに、今回の答えはこの違いが明快に答えられていて、なおさらすっきりいたしました。
ただ、マクロ内での「数値」と「文字」の使い分けのテクニックがまだ完全に理解できた
とは言えません。これを理解するためには、場を踏むしかないのではないかと思っています。
(もちろん勉強も必要ですが。)

 一つ皆様方にお詫びしなければならないことがあります。それは
  列 = Range("B1").Value + 8 = "9"
 の書き込みです。
 これはご指導いただいたコードですが実際は
 列 = Range("B1").Value + 8 ⇒ "9"
 と書かれていたものを "=" と変えてしまいました。このことにより誤解を与えてしまいました。
すみませんでした。(?)


 HANAさん、(みやほりん)(-_∂)bさん、Hatchさん、佳さん、(semm)さんありがとうございます。

 今回は、マクロの確認方法に「コードウィンドウ」を使用するということをプラスして
勉強いたしました。今読んでいる参考書にも同様の内容があったので、今回はすんなりと
確認できました。参考書も馬鹿にはできませんね。両名がおっしゃるととおりの結果が
でました。

 「列 = Month(DateSerial(2010, Sheets("集計欄(月)").Range("B1").Value - 5, 1)) + 1」
 このコードは「月」という観念をコードの中に取り入れて表示していると、捉えても
いいですね?これを貼り付け実行したところ正常に作動いたしました。ただこのテクニックは
まだ私の理解の範囲外です。「月」に関する関数を使用しているのではないかと想像しますが。
勉強を続けます。

 私は、マクロは一つの課題に対する正解は 一つまたそれに到達する道筋も一つだと思っていました。
日常使用している言葉、たとえば「明日」を表現するのに、「3月22日」と表現できますし、
「今日の次の日」と答えることもできます。これと同様マクロも課題に達する道筋は、何種類か
あるのですね。ただそれが間違っていれば、作動しませんが。

 今回は、多くの皆様方が長い間、みなさんに取っては低次元の質問に対して、根気よく、
丁寧に教えてくださったことに深く感謝いたします。まだまだ勉強不足の身ですので、今後も
勉強を、続けたいと思います。よろしくお願いいたします。中に失礼な言動もあったと思いますが
どうぞご容赦を。

 もしまだご指摘事項があれば書き入れてください。拝聴いたします。また今後私からの新たな
質問があるときは、新しいスレを作成いたします。(?)


 現在の疑問点が解消したら、その前の質問に戻ろうかと思っていたのですが
 どうやら、解消したのかしてないのかわからないまま 収束気味ですね?
 ってことで、とりあえず書こうと思っていた事をとりとめもなく書いてみます。

 みやほりんさんが上で書いておられますが
 変数の型を何にするのかは「何が欲しいか」によって変わります。

 1という数値が欲しいのか、1という文字が欲しいのか。
 数値と数字は使い分けも難しい所ですので、もっとわかりやすい所で
「1という数値が欲しいのか、Aという文字が欲しいのか」
 を気にしながら考えてみればよいと思います。

 VBAでセルを表す表現はいくつかあります。
 まず、A1セルを選択する行為をマクロの記録に取ると
  Range("A1").Select
 と記録されます。

 Range の後ろの括弧の中の「"A1"」部分は
 ""で囲ってあるので、文字ですね?

 それから、Cells で表す方法もあります。
 Cells(行 ,列)の順に書き、Cells(1 ,1) が、A1セルの事になります。
 この様に書いてあれば、この括弧の中にある「1」は数値です。

 前スレでは、 列="A",行=1 の様にデータを入れて
 列&行 = "A1" という文字を作り、Range の括弧の中に入れました。
 コードでは、変数の宣言から入りますが コード作成の流れとしては
 1.A1セルを表すのにどうやって表そうか?
    →Range("○×")を使うことにしよう
 2.今回は列と行は別々の要因で決まる(列は社名、行は月 で決まる)ので
   それぞれの変数を作ることにしよう
    →変数名は 列、行
 3.変数の型は何にすれば良いのだろう?
    列は、アルファベットだから 文字列型・・・"A1"の内"A"を入れる予定の変数
    行は、数だから、数値型・・・・・・・・・・"A1"の内 1 を入れる予定の変数
 この様に考えていき、コードの順番としては
 1.変数の宣言(列は文字列型、行は数値型)
 2.それぞれの変数に目的のデータを入れる
     行 = 1 , 列 = "A"
 3.それらを組み合わせて、セル番地を指定する
         Range(列&行)
 と、考えたのと逆方向に書くことになります。
   変数の宣言を先頭に持っていくのは、あくまでも
   「一般的な書き方」というレベルですが。

 では、Rangeを使って、A1:A5 の範囲を表したかったらどう書けば良いでしょう?
 たとえば "A" & 1 & ":" & "A" & 5 とすれば、A1:A5 になりますね?
 今回、1と5は固定です。変わるのは "A" の部分です。
 もしも、列 = "A" の様に列番号のアルファベットを入れることにすれば
  列 & "1:" & 列 & "5" これで、対応するセル範囲を表せそうです。

 Range("○×")と書こうと決めた段階で、変数「列」に入れるものは
  列番号のアルファベットでなくてはいけない
 となってしまいます。
 もしも列を算出する時にA,B,Cの様に列番号のアルファベットではなく
 1,2,3の様な数値しか得られないのなら、どうにかしてこの数値を
 列番号のアルファベットに直す必要があります。

 直す方法は、いくつかあるのですが。。。。
 「なんとかして、求められた1,2,3を直接使える方法はないか?」
 を考えてみてもよいと思います。

 後は「Range("○×")以外にセルを表す方法をどれだけ知っているか」が問題です。
 Cells(行,列)と書けば、列の部分はアルファベットでなくてもよい事はわかりましたね?

 すでにご理解いただけていると思いますが
 Cellsの括弧の後ろ側に入れるのは列を表す数で良いからです。
 (Range の"○×"の"○"部分はアルファベットが必須)

 変数「列」に数として取得されるなら、列も数を指定して使える
 Cells という書き方をするのが効率的です。

 単独のセルは、Cells(2, 列) で表すことが出来るとわかりました。
 これをセル範囲にする方法もいくつかあります。

 たとえば、みやほりんさんが書いておられる
 >.Range(.Cells(2 , 列) , .Cells(6 , 列)).Value = Sheets("集計欄(月)").Range("C3:C7").Value
 ●Range(セル1,セル2)
 これは、セル1〜セル2までの範囲 になります。
   作っておられるコードの中でも使ってありますね?
   >Range(Cells(上, 左), Cells(下, 右)).Select

 それから、semmさんが書いておられる
 > Sheets("集計欄(まとめ)").Cells(2, 列).Resize(5).Value = Range("C3:C7").Value
 ●セル1.Resize(5) 
 と書くと、セル1から行方向に5セル分の範囲 になります。
 「Resize(○)」で、行方向に○セル分 です。

 Resize(○,×)で、行方向に○セル,列方向に×セル分 です。
 イメージとして、ワークシート関数の OFFSET関数 OFFSET(基準,行数,列数,高さ,幅)の
 後半部分 高さ,幅 の部分と一致すると思います。

 今回は、OFFSETの使用を勧めてみようかと思っていました。
 たとえば、Range("A1:A5").Offset(, 5).Select と書くと
 F1:F5 の範囲が選択されます。
 A1:A5の次の列から5列隣の範囲です。
  これは、OFFSET関数の 行数,列数 の部分のイメージですね。

 基準となるセルは Range("A2:A6")で固定にして
 Range("B1").Value によって右にいくつオフセットすれば良いのか
 算出し、該当の部分に指定する。
Sub Test4()
    Dim シフト数 As Long
    If Range("B1").Value <= 5 Then
        列 = Range("B1").Value + 7
    Else
        列 = Range("B1").Value - 5
    End If
    Sheets("集計欄(まとめ)").Range("A2:A6").Offset(シフト数).Value = Range("C3:C7").Value
End Sub

 前回の質問と今回の質問の大きな違いは
  前回は、転記するセルの列のパターンが A,B,C の3つしかなかったが
   今回は、B〜 の12個ある。
 という点です。

 そして、計算で求めた場合の常として
  列番号のアルファベットよりも、列番号を表す数なら簡単に算出できた。
 が、ポイントになっていたと思います。

 おおざっぱな文章しか書いていませんので
 これからコードを作っていく場合には
 もっと細かい部分まで気を配っていく必要があると思いますが
 ご参考にしていただければと思います。

 (HANA)

 HANAさん早速のコメント有難うございます。

 マクロでは、セルの指定の仕方にもマクロの構成上、それに適した指定の仕方があるのですね。

 この質問をする前は、セルの指定は Range("A1")の形でできると思っていました。しかし、この指定
セルは固定されており、不特定セル(しかしセルの指定の決まりごとはある。)を指定する場合の
方法はどのようにすればよいのか解らず、悶々としていました。それが、Cells(○,△)とし、
○、△に対応する変数を数値または文字列で定義しそれに代入することで、不特定セルを指定できる
ことを勉強しました。さらにこれにOffset関数まで組み合わせて、使用できるとは思ってもいません
でした。今まで私の使用していたセルの指定はRange("○,△")以外は参考書の使えるコードを
作成マクロに合うように、修正し分けもわからず使用したら、たまたま思いどうり作動していたと
思われます。恥ずかしい話です。

 まだまだ勉強不足です。これで教わった内容のマクロコードは読めると思いますが、まだまだ、
自分でマクロコードを書くことはできないと思います。これを解決するためには、英語を
マスターするためには、英語圏の国に行き一人で生活すれば、自然と英語をマスターするように
マクロコードを自分で悩みながら作成するという場を踏まなければ身に付かないと思います。

 もちろん今回勉強したマクロの文法も理解してないとマクロの場合は、言葉の羅列では作動して
くれないですから。

 今後マクロをこれだけは絶対に知っていたほうがよいというマクロの文法があれば(これに
優劣をつけるのは間違いかも知れませんが。)ご教授願います。

 もし、何かご教授いただくことがあるのであれば、新しいスレを作成いたします。

 毎度毎度虫のよい話ばかりお願いして、恐縮に耐えません。(?)

 なんだかちょっとイメージが違う気がします。

 >マクロでは、セルの指定の仕方にもマクロの構成上、それに適した指定の仕方があるのですね。
 セルの指定の仕方に「いろいろな書き方がある」
 また、どの書き方をするのが良いかは
「セルを特定するための情報がどのように得られるかによって変わる」

 マクロの構成=コード の事であれば
 逆に、それに適したコードにしなくてはいけません。

 >セルの指定は Range("A1")の形でできると思っていました。しかし、・・・(以下略)
 の部分も、どういったことを言っておられるのか良く分かりません。

 前スレは、セルを指定するのに Rangeの形で指定していますよ?
 今回の問題でも、変数列に列を表すアルファベットが入る様にして
 Rangeの形で書くことも出来ます。

 具体的に例をあげて、
  こんなことを意図して書いた
  こんなコードは意図通りに動くけど
  こんなコードは動かず、こんな風になる
 と書いていただけると良いのですが。

 詳しく書いてもらえると、文字の印象でイメージに合わないだけで
 出来ないと思っておられることは本当に出来ないことなのかもしれません。

 長くなるようであれば、このスレでの概略も付けて
 新スレを作ってもらっても良いかもしれません。

 (HANA)

 こんにちは。佳です。

 > マクロでは、セルの指定の仕方にもマクロの構成上、それに適した指定の仕方があるのですね。

 いい勉強をされたと思います。
 今回は、Cells(数値,数値)がちょうどいい具合でしたが、場合によってはRange("A1")のほうがいいときもあります。
 今後、いろいろ勉強されるうちに そういう例にも出会われるでしょう。楽しみに勉強されて下さい。

 > これだけは絶対に(中略)文法
 文法ではありませんが、わたしは、マクロの記録をお勧めします。
 情報を引き出す力さえあれば、マクロの記録は情報の宝庫です。
 もうひとつお勧めなのが、入門書熟読です。
 本スレで学ばれたことは、たいていの入門書に載っています。
 ほかのひとに説明できるくらいしっかり読まれれば、ここで回答ができるくらいになれます。


 HANAさん、佳さんたびたびのコメント有難うございます。

 ここで続けます。

 マクロコードにおいて、セル"A1"の特定はRange("A1")でできると思います。しかし、あるデータを
その都度それに適したセルに書き写したいときは、Rangeをはじめいろんな指定の仕方があるのだな
と実感したと言うことです。

 また、HANAさんの言っておられる事は、マクロは人が操るものであって、人がマクロに操られる
ものではない、と私は理解しましたが、いかがでしょうか。マクロに対する具体的なことを
おっしゃっているのかも知れませんが。

 マクロには今まで教わった、いろんな決まりごとがあるではありませんか。私はそれを、マクロの
文法と呼びましたが、マクロを実践するためには、これの勉強は、絶対に必要と思っています。
 これを抵抗なく行うために、実践(マクロの記録)が、必要と感じて実践するつもりです。

 また、生意気なことを書いてしまいました。皆様の心遣いには心底感謝いたします。どんどん
アドバイスをお願いいたします。(?)

 コードを作れるようになるには、(?)さんも書いておられる様に
 場数を踏む事が大切だと思います。
 たくさん試して、たくさん悩んで
 なんとか動くコードをたくさん作っておくのが良いと思います。
  「コードを切り貼りして、適当に直して動かしたら動いたからOK」で終わるのではなく。

 既に出来ているコードも、ステップインで実行しながら
 動きや、各変数の値を確認していくと
 今なら多くのことが見えてくると思います。

 ハサミがあれば、紙を切ることが出来ます。
 カッターナイフでも、切れますね。
 さしを当てても、切れるかもしれません。

 どの道具を使うかは、その時の状況によって変わってくると思います。
 そして、どんな時にどの道具を使うのが適切かは、経験によって
 意識すること無く判断して、使い分けていると思います。

 まずは、どのような道具があれば紙を切れるか知っておかなくてはいけません。
 たくさん知っておくと、それだけ選択肢が広がりますね。
 より状況にあった道具を選べることになると思います。

 ハサミ・カッターナイフ 等が Range,Cells や Resize,Offset に当たると思います。
 (?)さんが書いておられる「マクロの文法」という部分かもしれません。
 いろんな人のコードを見て情報を仕入れても良いと思いますし
 マクロの記録をとって仕入れる事もできると思います。

 道具が揃ったら、後はどの場面でどの道具を使うのが良いのか
 自然と選択できる様になるまで繰り返し使ってみるのが良いと思います。

 その時、他の人が どんな場面でどのように使っているのか見て
 自分の知識にするのも良いと思います。
  (実践が一番身につくと思いますので、見るだけではなくやはり
   使ってみるのが良いと思いますが。)

 >これだけは絶対に知っていたほうがよいというマクロの文法
 文法ではありませんが、マクロの記録をとると
 ○○.Select Selection.××
 と言ったコードになっています。
 別のシートに関して処理をする場合も 一旦別のシートをSelectしてから
 アクティブシートに関して行われた操作が記録されます。

 しかし、なるべくセレクトしないコードになる様に
 心がけるのが良いと思います。
 セレクトすると、処理速度が落ちますし 画面がちらちらします。
 また、マクロの記録で出来たコードは、大きなものになると
 どのブックのどのシートのどのセルに関しての処理なのか
 分かりにくく成ってしまう場合が多いです。
    Sheets("集計欄(月)").Select
    Range("D1:G150").Select
    Selection.ClearContents
    Sheets("履歴").Select
    Range("A1").Select
 このあたりは簡単に、Selectを無くせると思います。 
   もちろん、その後の部分も思い通りに動くように
   Selectを無くしていかないといけませんが。

 この手のお話も割と良く行われるので、全文検索してみられると
 その様なスレッドがたくさん見つかると思います。

 がんばってください。

 (HANA)

HANAさん、有難うございます。

 今日は、この一言です。マクロ習得に向かってがんばります。

 一つだけ、HANAさんに習ったことを、使って

    Sheets("集計欄(月)").Select
    Range("D1:G150").Select
    Selection.ClearContents
    Sheets("履歴").Select
    Range("A1").Select

 を修正してみます。

   Sheets("集計欄(月)").Range("D1:G150").Select
   Selection.ClearContents
   Sheets("履歴").Range("A1").Select

 いかがでしょうか、すっきりしたと思いますが、正解でしょうか、それとも不正解でしょうか?

 (?)

 えーと。実行してみましたか?
 (semm)

 あっっ、衝突しちゃいました。。。

 最初の2行は、もうひとつ Select〜Selectionを無くして
   Sheets("集計欄(月)").Range("D1:G150").ClearContents
 の様に書けます。

 次の1行は、履歴シート以外が選択されている状態
 (たとえば、集計欄(月)シートがアクティブになっている状態)
 で実行すると、エラーになります。

 どんな感じになるのか修正コードを載せようかと思ったのですが
 どの範囲をどこにコピーすれば良いのか良く分からないので。。。

 履歴シートの表はA1セルから始まっていますか?
 見出しは何列目まで入っていますか?
 抽出後は何列:何列を、集計欄(月)シートの
 どこに貼り付けますか?

 (HANA)

 かっこつけて、書いちゃいましたが、書いた後テストを行ったら、エラーが出ました。
全く赤面の限りです。このスレの変更のやり方知らないので、そのままにしました。

 (履歴シート)
 最初4行にボタンを置き、5行めにそれぞれの項目をいれ実際のデータはA6セルからです。

 (集計欄(月)シート)
 履歴シートの検索結果をI3以下に項目を並べその下I4に貼り付け、そのデータをさらに
先の空白列A〜F列にまとめています。C3には月数があり、(集計欄(まとめ))シートに
転記するデータはF5〜9にあります。

 (集計欄(まとめ)シート)
 4行のB(B4)から月数を入れA5からA9まで対応する項目名を入れ、集計欄(月)シートで
まとめたF5〜F9のデータを対応月に貼り付けています。

 以上がデータ作成の組み立てです。最初に示したサンプルと位置はずれていますが、教えて
いただいたコードを直しながら今まで対応してきました。(私自身その作業でトラブルの
発生もありましたが、それも勉強と、やってきました。最初に示したコードに食い違いが
あったのはそのためです。(?)

 1.履歴シートの1〜4行目には何が入っていますか?
 2.見出しは何列目まで入っていますか?
 3.抽出後は何列:何列を、集計欄(月)シートに貼り付けますか?
 4.実際のデータで動かしている、前半(抽出)部分のコードを載せて下さい。

 (HANA)


 1.マクロを実行するための表示-ツールバーフォームから作成したコマンドボタン3個と、オートシェイブ-
基本図形-額縁にマクロを登録したボタンだけで、セルにデータは何も入れていません。

 2.列の見出しはありません。

 3.A列からJ列を集計欄(月)シートに貼り付けます。

 4.Private Sub CommandButton1_Click()
    Dim 列 As Long

    検索開始日 = ">=" & UserForm2.TextBox1.Text
    検索終了日 = "<=" & UserForm2.TextBox2.Text
    Sheets("集計欄(月)").Select
    Range("j4:s150").Select
    Selection.ClearContents
    Sheets("テスト履歴").Select
    Range("A5").Select
    Selection.AutoFilter
    Selection.AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日
      上 = 6                                  '基点セルの行番号(この場合はA1の1) ※2
        左 = 1                                  '基点セルの列番号(A1のAの数字表記) ※2
        下 = Range(Cells(上, 左), Cells(上, 左)).End(xlDown).Row       '下端検出
        右 = 10 '右端検出
    Range(Cells(上, 左), Cells(下, 右)).Select  '検出した範囲を選択
    Selection.Copy
    Sheets("集計欄(月)").Select
    Range("J4").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    Range("J3").Select
    Sheets("テスト履歴").Select
    Selection.AutoFilter
    Range("A3").Select
    Sheets("集計欄(月)").Select

    列 = Month(DateSerial(2010, Sheets("集計欄(月)").Range("c3").Value - 5, 1)) + 1
    With Sheets("集計欄(まとめ)")
        .Range(.Cells(5, 列), .Cells(9, 列)).Value = Sheets("集計欄(月)").Range("f5:f9").Value
    End With
 End Sub

 これがマクロコードすべてです。(冒頭のスレに記入しているマクロです。違っているところは、
皆さんにご指導いただいて修正したところです。またシート1の名称が変わっていますが、
これが私が実際につけている名称です。)

 それとこれには関係あるかどうか解りませんが、1〜5行目まで固定し空白欄にデータを追加する時
空白欄までスクロールし、記入するデータの項目を間違えないようにしています。(?)

 でしたら、こんな感じで良いと思います。

 '------
Sub データ転記()
Dim 検索開始日 As String, 検索終了日 As String

    検索開始日 = ">=" & UserForm2.TextBox1.Text
    検索終了日 = "<=" & UserForm2.TextBox2.Text

    Sheets("集計欄(月)").Range("J4:S150").ClearContents
    With Sheets("テスト履歴")
        .Range("A5").AutoFilter Field:=3, _
            Criteria1:=検索開始日, Operator:=xlAnd, Criteria2:=検索終了日
        .AutoFilter.Range.Offset(1).Copy Sheets("集計欄(月)").Range("J4")
        .AutoFilterMode = False
    End With
End Sub
 '------

 ちょっとものぐさコードです。

 AutoFilter.Range で、オートフィルタが設定されている範囲を
 取得しました。

 With 〜 End With の間に挟まっている部分で
 「.」の前には、With の後ろの部分が省略されていると思って下さい。

 例えば、End With の一つ上の行は With が無かった場合
   Sheets("テスト履歴").AutoFilterMode = False
 と書いてあるのと同じに成ります。

 色々な物・・・Range(セル)とか、オートフィルタ・・・のそれぞれに
 「どのシートの」と言うのを付け加えていくと
 そのシートを選択しなくても
 指定したシートへ処理されます。
 コピーや削除をする際も、「どのセルを」と書いておけば
 そのセルを選択する必要がなくなります。

 「Option Explicit」の記入と変数の宣言は
 やるようにして於かれた方が良いと思います。

 (HANA)

 HANAさんたびたび有難うございます。

 早速、このコードでやって見ました。見事に正常な作動をしました。

 私の作成したコードは185行、皆様方に指導いただいて、1回目の修正したコードは40行、
2回目は31行、最後にHANAさんに教えていただいたものは20行、当初のコードと比べると
約20分の1になっています。驚きです。すべて正常に作動いたしますが、表現の仕方で、
こんなにも短くできるのですね。この効率のよい表現ができるよう私も勉強いたします。

 一つ質問です。今回HANAさんにご指導いただいたコードの中に

 Sheets("集計欄(月)").Range("J4:S150").ClearContents

 とありますが、

 Sheets("集計欄(月)").Select
    Range("D1:G150").Select
    Selection.ClearContents
    Sheets("履歴").Select
    Range("A1").Select

 以前私がこれを修正してエラーの出たコード

  Sheets("集計欄(月)").Range("D1:G150").Select
   Selection.ClearContents
   Sheets("履歴").Range("A1").Select

 Sheets("集計欄(月)").Range("D1:G150").ClearContents
 Sheets("履歴").Select
 Range("A1").Select

 とすべきだったのでしょうか。(?)


 はい、済みません。
 その部分は引用箇所が少なかったです。

 アクティブでないシートのセルは選択出来ないので
 履歴以外のシートがアクティブの時
 >Sheets("履歴").Range("A1").Select
 と書いてしまうとエラーになります。

 どうしても他のシートのセルを選択する必要が有るのなら
 .Select を使って書く場合
 >Sheets("履歴").Select
 >Range("A1").Select
 の様に2行にしないといけません。

 でも、以降の部分も踏まえて 選択する必要が有るかどうか
 判断が必要だと思います。

 この3行が
    Sheets("集計欄(月)").Select
    Range("j4:s150").Select
    Selection.ClearContents
 この1行になりました。
    Sheets("集計欄(月)").Range("D1:G150").ClearContents

 次の固まりは
    Sheets("テスト履歴").Select
    Range("A5").Select
    Selection.AutoFilter
    Selection.AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日
 区切りをつけるならこの5行(4行?)でした。

 まず、3行目の Selection と言うのは
 テスト履歴シートのA5セルの事なので
    Sheets("テスト履歴").Range("A5").AutoFilter
 次の、Selection.AutoFilter のSelection も、同じですよね。。。
 別に3行目の「Selection.AutoFilter」を実行したら選択範囲が変わるわけでは無いので。
    Sheets("テスト履歴").Range("A5").AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日
 ここで【試しに】上側の一行を消して動かしてみると
 ちゃんと動くので下側の一行だけ残します。
    Sheets("テスト履歴").Range("A5").AutoFilter Field:=3, Criteria1:=検索開始日, Operator:=xlAnd _
        , Criteria2:=検索終了日

 こうやってセル番地がどのシートのなのか書いてあって
 更に、コード内から Selection がなくなったので
 どのシートがアクティブに成っていても、どのセルが選択されていても
 この操作は、テスト履歴シートのA5セルに対して行われるように成ります。

 (HANA) 


 HANAさん有難うございます。

 その後、何点かのマクロを作成しました。作成後そのマクロを実行して、エラーが
出ることが、ありましたが、皆さんのご指導のおかげで、今のところ、正常に
作動しております。ただ、作成マクロを皆さんに添削していただいたら、まだまだ、
50点が取れたらいいマクロだと思いますが。今後ますます精進し100点が取れる
マクロを作成するようがんばります。また、新たな疑問が発生することもあると
思いますが、そのときは新しいスレを作成し質問させていただきます。

 今回の質問についてはHANAさん初め多数の方にご回答いただき有難うございました。
ご回答いただいた皆様方に御礼申し上げます。(?)

コメント返信:

[ 一覧(最新更新順) ]


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