質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

760閲覧

売上管理シートの作成

arin

総合スコア5

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2021/11/25 10:17

編集2021/11/30 06:15

売上管理シート作成

現在売上管理シートをを作成していて、連番と重複を1行にまとめるコードをを調べながら書いてる途中です。
下記の項目機能を作成したいのですが、全くわからないので下記の項目が動くコード教えてもらえると幸いです。

・「No」は1からの連番を振り、1回の会計で1つのNoとする
・1商品毎1行で表記する(同一会計内において、「No」と「販売日時」は垂直方向でセル結合をする)
・「販売日時」は「会計」ボタンをを押した時点の日時とし、「YYYY/MM/DD hh:mm」の形式とする
・価格を表示する部分は「¥9,999(¥は半角文字)」の形式とし、数字は整数表記とする
・「販売額」は [単価×販売数]で計算する

会計ボタンを押すと、明細シートのA1セル「商品コード」B1セル「商品名」C1セル「単価」の下に情報が記入された後に、売上管理シートに「No」「販売日時」「商品コード」「商品名」「単価」「販売数」「販売額」データを反映したいです。

削除ボタンがあるので、会計ボタンを押した後は明細シートの情報を消します。

会計ボタンを押した後の明細シート↓
明細シート
現在の売上管理シート↓
イメージ説明
売上管理シート完成見本↓
売上管理シート

会計ボタン

VBA

1'会計 2Sub Total() 3'売上管理のシートにNo、販売日時、商品コード、商品名、単価、販売数、販売額を記入 4 Dim lngNo As Long 5 Dim strNitiji As String 6 strNitiji = Format(Now, "YYYY/MM/DD hh:mm") 7 Dim lngEndRow: lngEndRow = Worksheets("売上管理").Cells(Rows.Count, 1).End(xlUp).Row 8 Dim Arow As Long 9 Dim i As Long, j As Long, k As Long 10 k = 0 11 Dim myDic As Object 12 Dim mykeys, myItems 13 Dim varArrayItems As Variant 14 Dim ProductCode, ProductName, Tanka, Hanbaisuu, Hanbaigaku 15 'Setステートメントで戻り値をオブジェクト変数に代入する 16 Set myDic = CreateObject("Scripting.Dictionary") 17 18 'A列でリストの最終行を調べる 19 Arow = Worksheets("明細").Cells(Rows.Count, 1).End(xlUp).Row 20 21 With Worksheets("明細") 22 For i = 2 To Arow 23 ProductCode = .Cells(i, 1).Value 24 If myDic.Exists(ProductCode) = False Then 25 ProductName = .Cells(i, 2).Value 26 Tanka = .Cells(i, 3).Value 27 Hanbaisuu = Application.WorksheetFunction.CountIf(.Range("B:B"), .Cells(i, 2).Value) 28 Hanbaigaku = Tanka * Hanbaisuu 29 varArrayItems = Array(ProductName, Tanka, Hanbaisuu, Hanbaigaku) 30 myDic.Add ProductCode, varArrayItems 31 End If 32 Next 33 End With 34 With Worksheets("売上管理") 35 .Cells(lngEndRow, 2).End(xlUp).Offset(1).Value = strNitiji 36 For j = 0 To myDic.Count - 1 37 mykeys = myDic.Keys 38 myItems = myDic.Items 39 '販売日時、商品コード、商品名、単価、販売数、販売額を表示する 40 .Range("A" & j + 2).Value = lngNo + 1 41 .Range("B" & j + 2).Value = strNitiji 42 .Range("C" & j + 2).Value = mykeys(j) 43 .Range("D" & j + 2).Value = myItems(j)(k) 44 .Range("E" & j + 2).Value = myItems(j)(k + 1) 45 .Range("F" & j + 2).Value = myItems(j)(k + 2) 46 .Range("G" & j + 2).Value = myItems(j)(k + 3) 47 k = 0 48 Next j 49 End With 50 51 'Dictionaryを初期化 52 myDic.RemoveAll 53 54End Sub

補足情報(FW/ツールのバージョンなど)

office365Excell

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2021/11/25 10:55

> 現在売上管理シートを調べながら作成してるのですが、わからないので教えてもらえると幸いです。 何を「教えてもら」いたいのでしょうか? どこまで出来ていてどこで困っているのでしょう?
arin

2021/11/25 11:23

申し訳ございません。 説明文の追加編集しましたので確認よろしくお願いします。
guest

回答1

0

ベストアンサー

修正して再掲。

VBA

1Sub total() 2 '売上管理のシートにNo、販売日時、商品コード、商品名、単価、販売数、販売額を記入 3 Dim k 4 Dim lngNo As Long 5 Dim strNitiji As String 6 Dim varKodoNamePrice As Variant 7 strNitiji = Format(Now, "YYYY/MM/DD hh:mm") 8 Dim lngEndRow: lngEndRow = Worksheets("売上管理").Cells(Rows.Count, 1).End(xlUp).Row 9 Dim Arow As Long 10 Dim i As Long, j As Long 11 Dim myDic As Object 12 Dim mykeys, myItems 13 Dim varArrayItems As Variant 14 Dim ProductCode, ProductName, Tanka, Hanbaisuu, Hanbaigaku 15 Set myDic = CreateObject("Scripting.Dictionary") 16 17 'A列でリストの最終行を調べる 18 Arow = Worksheets("明細").Cells(Rows.Count, 1).End(xlUp).Row 19 20 With Worksheets("明細") 21 For i = 2 To Arow 22 ProductCode = .Cells(i, 1).Value 23 If Not myDic.Exists(ProductCode) Then 24 ProductName = .Cells(i, 2).Value 25 Tanka = .Cells(i, 3).Value 26 Hanbaisuu = WorksheetFunction.CountIf(.Columns(1), ProductCode) 27 Hanbaigaku = Tanka * Hanbaisuu 28 varKodoNamePrice = Array(ProductCode, ProductName, Tanka, Hanbaisuu, Hanbaigaku) 29 '連想配列、キーとデータを追加する 30 myDic.Add ProductCode, varKodoNamePrice 31 End If 32 Next i 33 End With 34 35 With Worksheets("売上管理") 36 myItems = myDic.Items 37 For j = 0 To myDic.Count - 1 38 'キーとデータをセルに表示する 39 .Cells(lngEndRow, 1).Offset(1 + j, 2).Resize(, 5).Value = myItems(j) 40 Next j 41 42 lngNo = WorksheetFunction.Max(.Columns(1)) + 1 43 .Cells(lngEndRow, 1).Offset(1).Resize(, 2).Value = Array(lngNo, strNitiji) 44 .Cells(lngEndRow, 1).Offset(1).Resize(myDic.Count).Merge 45 .Cells(lngEndRow, 2).Offset(1).Resize(myDic.Count).Merge 46 End With 47End Sub 48

<追記> 整理整頓。

VBA

1Sub total() 2 3 'シートの準備 4 With ThisWorkbook 5 Dim meisai As Worksheet 6 Dim urikan As Worksheet 7 Set meisai = .Worksheets("明細") 8 Set urikan = .Worksheets("売上管理") 9 End With 10 11 '明細を取得し集計 12 With meisai 13 '連想配列(重複除去用)の準備 14 Dim myDic As Object 15 Set myDic = CreateObject("Scripting.Dictionary") 16 17 '明細データの格納 18 Dim ProductCode, ProductName, Tanka, Hanbaisuu, Hanbaigaku 19 Dim varKodoNamePrice As Variant 20 Dim i 21 For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row 22 ProductCode = .Cells(i, 1).Value 23 If Not myDic.Exists(ProductCode) Then 24 ProductName = .Cells(i, 2).Value 25 Tanka = .Cells(i, 3).Value 26 Hanbaisuu = WorksheetFunction.CountIf(.Columns(1), ProductCode) 27 Hanbaigaku = Tanka * Hanbaisuu 28 varKodoNamePrice = Array(ProductCode, ProductName, Tanka, Hanbaisuu, Hanbaigaku) 29 myDic.Add ProductCode, varKodoNamePrice 30 End If 31 Next i 32 33 '出力用配列の準備 34 Dim myItems As Variant, myCount As Long 35 myItems = WorksheetFunction.Transpose(WorksheetFunction.Transpose(myDic.Items)) 36 myCount = myDic.Count 37 End With 38 39 40 '売上管理に出力 41 With urikan 42 '開始行の決定 43 Dim lngNewRow As Long 44 lngNewRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1).Row 45 46 '連番、日付の決定 47 Dim lngNo As Long, strNow As String 48 lngNo = WorksheetFunction.Max(.Columns(1)) + 1 49 strNow = Format(Now, "YYYY/MM/DD hh:mm") 50 51 '連番、日付の出力、セル結合 52 .Cells(lngNewRow, 1).Resize(, 2).Value = Array(lngNo, strNow) 53 .Cells(lngNewRow, 1).Resize(myCount).Merge 54 .Cells(lngNewRow, 2).Resize(myCount).Merge 55 56 '明細の出力 57 .Cells(lngNewRow, 3).Resize(myCount, 5).Value = myItems 58 End With 59 60End Sub

投稿2021/11/25 14:48

編集2021/11/30 06:59
jinoji

総合スコア4585

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

arin

2021/11/25 16:21

jinojiさん回答ありがとうございます。 教えてもらったコードを組み込み考えると、現在のコードのIf文は必要ないようになりますね。 元コードのどこが気になったのですか?
jinoji

2021/11/25 23:38

On Error Resume Next のせいでエラーにならないだけで RangeItems あたりの処理が正しく書けてないと思います。 キー重複の時のエラーを回避するなら、 たとえば If Not myDic.Exists(xx) Then のような If文を入れることで実現できます。 安易にOn Error Resume Nextを使わない方がいいです。 もう一つ、jのForループは i のForループの中でなく i を回し終わった後にする方が適切だと思います。 こちらは同じことを繰り返して無駄になるだけで結果は変わらないはずなので 実害はないと思いますが。
arin

2021/11/26 10:29 編集

すみません。 今更ながら.Existsを知り書いておりました。 下記のように組み替えてい最初のIf文でエラーが「オブジェクト変数または With ブロック変数が設定されていません。」と出てきたのですが何処のSetが抜けているのですか? ``` '売上管理のシートにNo、販売日時、商品コード、商品名、単価、販売数、販売額を記入 Dim lngNo As Long Dim strNitiji As String Dim varKodoNamePrice As Variant strNitiji = Format(Now, "YYYY/MM/DD hh:mm") Dim lngEndRow: lngEndRow = Worksheets("売上管理").Cells(Rows.Count, 1).End(xlUp).Row Dim Arow As Long Dim i As Long, j As Long Dim myDic As Object Dim mykeys, myItems Dim varArrayItems As Variant 'A列でリストの最終行を調べる Arow = Worksheets("明細").Cells(Rows.Count, 1).End(xlUp).Row With Worksheets("明細") Dim c, n, t, s, g, arr For i = 2 To Arow Set c = .Cells(i, 1).Value If Not myDic.Exists(c) Then n = .Cells(i, 2).Value t = .Cells(i, 3).Value s = WorksheetFunction.CountIf(.Columns(1), c) g = t * s arr = Array(c, n, t, s, g) '連想配列、キーとデータを追加する myDic.Add c, arr End If Next i End With With Worksheets("売上管理") lngNo = WorksheetFunction.Max(.Columns(1)) + 1 .Cells(lngEndRow, 1).Offset(1).Value = lngNo .Cells(lngEndRow, 1).Offset(1).Resize(myDic.Count).Merge .Cells(lngEndRow, 2).Offset(1).Resize(myDic.Count).Merge myItems = myDic.Items For j = 0 To myDic.Count - 1 'キーとデータをセルに表示する .Range("C" & j + 2).Resize(, 5).Value = myItems(j) Next j End With ```
jinoji

2021/11/26 11:28

Set c = .Cells(i, 1).Value だと文法上おかしくて、 c = .Cells(i, 1).Value か Set c = .Cells(i, 1) のどちらか。
arin

2021/11/29 02:28 編集

本当にすみません。 どちらでも同じ文言のエラーおきますね
jinoji

2021/11/29 09:55

Set myDic = CreateObject("Scripting.Dictionary")をしてないから
arin

2021/11/29 13:14

Noが一番から出来ないのと一度コードで登録すると、削除ボタンで明細シートを初期化時に再度売上管理に登録出来ないのですが、Keyを初期すれば良いのですか?
jinoji

2021/11/30 00:53

lngNo の処理がない If myDic.Exists(ProductCode) = False Then の場所がおかしい
arin

2021/11/30 01:33

回答にあるコードでその結果です。 Noが一番から出来ないのと一度コードで登録すると、削除ボタンで明細シートを初期化時に再度売上管理に登録出来ないのです。
jinoji

2021/11/30 01:40 編集

Noが一番から出来ないとは具体的にどうなるのですか(そしてどうなってほしいのですか)
arin

2021/11/30 02:04

連番が1番からではなく2番からになっているので、1番から連番が振れるようにしたいのと、一度コードでDictionaryに登録すると、削除ボタンで明細シートを初期化時に再度同じ売上管理に登録出来ないのですが、Keyを初期すれば良いのですか?
arin

2021/11/30 06:31 編集

再掲ありがとうございます! 現状の売上管理の連番が1番からではなく2番からになっている現象がIf文で解決出来ました。 jinojiさん本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問