よくある例なのですが、、、「売上一覧」から、必要な項目にカーソルを合わせて、ボタンを押すとその行に記載されている項目の請求書が完成するというものをエクセルで作成したいと考えてます。
サンプルをひっぱってきて編集すればできると思っていたのですが、うまくいきません。
下記URLにソースのサンプルがあります。できれば英和辞典のようにソースの意味を一文一文教えていただきたいです。
ご面倒なお伺いで大変申し訳ございません。
http://www.geocities.jp/misuzu_su_1016/html.html
たぶん難しいのはオートフィルタぐらいだと思います
オートフィルタの説明
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_autofilter.ht...
あとは、どのセルを選択しているかをイメージすれば理解しやすいと思います。
説明自体は殆どプログラム通りなので、説明になってるかどうか・・・
Sub 請求書作成()
Dim 受注番号 As String
Dim 受注日 As Date
Dim 顧客名 As String
Dim 列数 As Integer
Dim 行数 As Integer
'カーソルで選択しているセルの値を受注番号に入れる
受注番号 = Selection.Value
'選択しているセルから相対位置(0, 1)の値を受注日に入れる
受注日 = Selection.Offset(0, 1).Value
'選択しているセルから相対位置(0, 2)の値を受注日に入れる
顧客名 = Selection.Offset(0, 2).Value
「請求書」シートの範囲(A10:D1)をクリアする
Worksheets("請求書").Range("A10:D17").ClearContents
'オートフィルタの設定
'Field:フィルタの対象となるフィールド番号を整数で指定
'Criteria1:抽出条件となる文字列 (選択している受注番号) を指定
Selection.AutoFilter Field:=1, Criteria1:=Selection.Value
'オートフィルタによって絞り込まれた領域を選択
Selection.CurrentRegion.Select
'選択している範囲の列数を取得
列数 = Selection.Columns.Count
'選択している範囲の行数を取得
行数 = Selection.Rows.Count
'選択している範囲から相対位置(1, 3)のセルを選択
Selection.Offset(1, 3).Select
'選択している範囲から(行数 - 1, 列数 - 3)のセル範囲に変更する
Selection.Resize(行数 - 1, 列数 - 3).Select
'選択している範囲をコピー
Selection.Copy
'「請求書」シートを選択
Sheets("請求書").Select
'「請求書」シートのA10を選択
Range("A10").Select
'選択されているセル("A10")に値を貼り付け
Selection.PasteSpecial Paste:=xlValues
'セル("D6")に受注番号をセットする
Range("D6").Value = 受注番号
'セル("D7")に受注日をセットする
Range("D7").Value = 受注日
'セル("A6")に顧客名をセットする
Range("A6").Value = 顧客名
'「売上」シートを選択
Sheets("売上").Select
'オートフィルタの解除
Selection.AutoFilter
'セル("A4")を選択
Range("A4").Select
'「請求書」シートを選択
Sheets("請求書").Select
End Sub
このマクロで行われていることを説明します。
例えば売上シートはこんな表になるかと思います。
A | B | C | D | E | F | G | |
---|---|---|---|---|---|---|---|
1 | 受注番号 | 受注日 | 顧客名 | 商品 | 個数 | 単価 | 金額 |
2 | 1 | H22.2.4 | 田中 | りんご | 2 | 100 | 200 |
3 | 2 | H22.2.5 | 佐々木 | みかん | 3 | 50 | 150 |
4 | 3 | H22.2.6 | 木村 | いちご | 2 | 150 | 300 |
5 | 1 | H22.2.4 | 田中 | みかん | 5 | 50 | 250 |
6 | 1 | H22.2.4 | 田中 | いちご | 3 | 150 | 450 |
7 | 2 | H22.2.5 | 佐々木 | りんご | 2 | 100 | 200 |
このシートからA2セルの1を選択して実行すると受注番号フィルターで1だけが表示されます。・・・①
A | B | C | D | E | F | G | |
---|---|---|---|---|---|---|---|
1 | 受注番号 | 受注日 | 顧客名 | 商品 | 個数 | 単価 | 金額 |
2 | 1 | H22.2.4 | 田中 | りんご | 2 | 100 | 200 |
3 | 1 | H22.2.4 | 田中 | みかん | 5 | 50 | 250 |
4 | 1 | H22.2.4 | 田中 | いちご | 3 | 150 | 450 |
次にC2からG4までを選択して・・・②
請求書シートの方に値だけコピーします。・・・③
わかりづらいと感じるのはたぶんここで、行数から1引いて、列数から3を引いてるのは
見出しと最初の3行はコピーする必要がないからということです。
請求書シートはこのようになります。
A | B | C | D | |
---|---|---|---|---|
6 | 田中 | 1 | ||
7 | 2010/2/4 | |||
8 | ||||
9 | 商品 | 個数 | 単価 | 金額 |
10 | りんご | 2 | 100 | 200 |
11 | みかん | 5 | 50 | 250 |
12 | いちご | 3 | 150 | 450 |
13 | ||||
14 | ||||
15 | ||||
16 | ||||
17 |
Sub 請求書作成() '変数を宣言しています Dim 受注番号 As String Dim 受注日 As Date Dim 顧客名 As String Dim 列数 As Integer Dim 行数 As Integer 'Selectionは選択したセルなので選択したセルの値が[受注番号]に入ります 受注番号 = Selection.Value 'Offsetは下にいくつ右にいくつを意味します。 'つまり選択したセルから下に0右に1のセルの値が[受注日]に入ります 受注日 = Selection.Offset(0, 1).Value 顧客名 = Selection.Offset(0, 2).Value '請求書シートのA10からD17の範囲の文字を消します Worksheets("請求書").Range("A10:D17").ClearContents 'フィルターをかけて選択したセルと同じセルの行以外を非表示にします・・・① Selection.AutoFilter Field:=1, Criteria1:=Selection.Value '選択したセルを含む表全体を選択します Selection.CurrentRegion.Select '選択した表全体の列数と行数を変数に代入 列数 = Selection.Columns.Count 行数 = Selection.Rows.Count '選択した表の左上から下に1右に3のセルを選択・・・② Selection.Offset(1, 3).Select '選択範囲を下に[行数]-1右に[列数]-3に広げます Selection.Resize(行数 - 1, 列数 - 3).Select '選択範囲をコピーします Selection.Copy '請求書シートを開きます Sheets("請求書").Select 'A10セルを選択して値だけをコピーします・・・③ Range("A10").Select Selection.PasteSpecial Paste:=xlValues '受注番号、受注日、顧客名と記入 Range("D6").Value = 受注番号 Range("D7").Value = 受注日 Range("A6").Value = 顧客名 '売上シートに戻ってフィルターを解除してA4セルを選択 Sheets("売上").Select Selection.AutoFilter Range("A4").Select '請求書シートを開く Sheets("請求書").Select End Sub
ありがとうございます!
例付きでご回答いただけましてとても参考になりました。
ひとつひとつの意味がとても理解しやすいです。
フィルターとか非表示とかの解釈ができていなかったことがわかりました。
ありがとうございます★
どこがうまくいかないのでしょうか?
かなり限定条件で動く作りですのでおそらく
レイアウトが合ってないんだと思います
サンプルがネット上であればソースを示した方がいいと思います
前提条件;
・「売上」という名前のシートのA列から順に
「受注番号」「受注日」「顧客名」「張り付け項目(4列)」の順に列があり
最初の行に列名が書いてある
・「請求書」という名前のシートがあり
A10〜D17のエリアが書き換えられる
従って同じ受注番号の明細は最大8つ
・マクロ開始前に「受注番号」「受注日」「顧客名」「張り付け項目(4列)」
の7マスまたは行を選択した状態でマクロを呼び出す
Dim 受注番号 As String
Dim 受注日 As Date
Dim 顧客名 As String
Dim 列数 As Integer
Dim 行数 As Integer
変数宣言です。作業用の準備です
受注番号 = Selection.Value
受注日 = Selection.Offset(0, 1).Value
顧客名 = Selection.Offset(0, 2).Value
選択した3マスの左から順に必要な情報を記憶します(*)
Worksheets("請求書").Range("A10:D17").ClearContents
「請求書」シートのA10〜D17を消去します
Selection.AutoFilter Field:=1, Criteria1:=Selection.Value
オートフィルタを1列目=受注番号に設定し選択している受注番号で絞りこみます
Selection.CurrentRegion.Select
絞り込んだ結果全体(7列x(列名行+絞り込まれた行数))を選択します
列数 = Selection.Columns.Count
行数 = Selection.Rows.Count
選択範囲の列数と行数を記録します
Selection.Offset(1, 3).Select
選択範囲の左上から1行下、3列右を選択します。
つまり絞り込まれたデータの列名行の下の
「張り付け項目(4列)」の最初の列を選択します
Selection.Resize(行数 - 1, 列数 - 3).Select
選択エリアをデータの右下まで拡張します
Selection.Copy
選択範囲をコピーします
Sheets("請求書").Select
「請求書」シートを選択します
Range("A10").Select
セルA10を選択します
Selection.PasteSpecial Paste:=xlValues
値(数字や文字で書式は含まない)の張り付けを行います
Range("D6").Value = 受注番号
Range("D7").Value = 受注日
Range("A6").Value = 顧客名
最初(*)で記憶したものを記入します
Sheets("売上").Select
Selection.AutoFilter
売り上げシートを選択肢先ほど設定したオートフィルタを解除します
Range("A4").Select
A4(貼付け項目の最初)を選択します(次回作業用)
Sheets("請求書").Select
「請求書シート」を選択します
ありがとうございます。
ご丁寧にリファレンスいただきまして、とても参考になりました。
がんばります★
回答者 | 回答 | 受取 | ベストアンサー | 回答時間 | |
---|---|---|---|---|---|
1 | jp---jp | 41回 | 16回 | 1回 | 2010-02-11 22:34:50 |
ありがとうございます。
なるほどですね!
おそらく自動で行われている過程が頭に入ってなくて・・
いきなり結果が反映する頭でいて・・・
日本語の部分を書き換えれば良いと考えていたのでさっぱり「?」がうかんでいたのかもしれません。
ありがとうございます。
大変参考になりました。