
Office2019を使っています。
下記の様なデータがあります。
ID、商品名1、型番1、商品名2、型番2 ~ 商品名10、型番10
1レコードが、1つのIDに対して最大10個までの商品名と型番が入っており、
20万行以上あり、毎日増え続けている状況です。
やりたい事は、
ID、商品名1、型番1
ID、商品名2、型番2
ID、商品名3、型番3
~
ID、商品名10、型番10
の様に、商品名と型番を縦に並べる作業です。
Powerクエリーでいう「ピボットの解除」と同じ処理でしょうか?
現在は何とか手作業でやっています。
ここで問題点があり、すぐにお気づきになられると思いますが、
20万行もあると商品名5個を縦に並べた段階で100万行に達してしまいます。
しかし、商品名2以降にはデータが入ってないレコードが結構あり、
空行を削除するとぐっと縮まるんです。
なのでギリギリまで縦につなげて、空行を削除してまたつなげるを繰り返して実現しています。
上記を踏まえて相談したい内容は、
空データを無視(又は削除)しながら、ID、商品名、型番を縦に並べるにはどうしたら良いでしょうか?
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> 新しいCSVで更新をかけると約50分かかる
リンクテーブルになってないですかね?
リンクテーブルは遅いので、インポートしちゃって下さい。
>解決できるようにはなりました
それは何よりです。
>もっと早くする方法があったら嬉しいです。
最低限しかしてないですけど、#3 はご質問文の仕様に従い、25万件のサンプルデータを4秒弱で CSV に書き出してます。80万件以下になるなら CSVを Excel で開き直しても1分がいいとこでしょう。
試す価値もないでしたかね?
いえいえ、とにかく時間内に終わらせなければいけなく、
新しい試みにトライする余裕がありませんでした。
そんなに効率良く済む可能性があるなら早く試すべきでした。
時間を見て試したいと思います。
まずセル位置とか読み解いて実際のフォーマットに当てはめなきゃいけないんですよね。。。
頑張ります
No.3
- 回答日時:
こんにちは。
既に100万行超えがわかっているなら、最早 Excel の範疇ではありません。Access などのデータベースを使った方が良いでしょう。
とりま、100万件は超えるのだろうから CSV に書き出してみました。
件数多いので
配列で処理すべき?
テキスト書き出しは ADO STREAMが速い?
とか色々考えましたが、途中で面倒になってダレてます☆
そこそこ速いと思いますが、凝らずに普通に書いても十分だったかもしれない。ご参考程度に。
レイトバインド嫌いなので、VBE で次の参照設定して下さい。
Microsoft ActiveX Data Objects x.x Library
(x.x はお使いの環境によって異なりますが最新のものを)
エラートラップとか保存場所とかは適当にやって下さい。
Sub sampleProc()
'スピードも速くならないしエラーの原因になるので大きくし過ぎない
Const MAX_BUFFER_SIZE As Long = 20000
Dim src_data As Range
Dim adoStream As ADODB.Stream
Dim srcBuf As Variant
Dim outBuf As Variant
Dim src_row As Long, src_col As Long
Dim loop_count As Long
Dim i As Long
Dim pos As Long
'データ範囲
Set src_data = ThisWorkbook.Worksheets("Sheet1").Range("A1").CurrentRegion
'見出しがあるならデータ範囲から除去
Set src_data = src_data.Offset(1).Resize(src_data.Rows.Count - 1)
'データ読込回数
loop_count = Application.WorksheetFunction.RoundUp(src_data.Rows.Count / MAX_BUFFER_SIZE, 0)
'CSVデータ出力準備
Set adoStream = New ADODB.Stream
adoStream.Charset = "UTF-8"
adoStream.Open
'データ読込→整形→CSV書き出し
ReDim outBuf(1 To 3)
pos = 1
For i = 1 To loop_count
srcBuf = Range(src_data.Rows(pos), src_data.Rows(pos + MAX_BUFFER_SIZE - 1)).Value
'
For src_row = 1 To UBound(srcBuf)
For src_col = 2 To UBound(srcBuf, 2) Step 2
If Len(srcBuf(src_row, src_col)) Then
outBuf(1) = srcBuf(src_row, 1)
outBuf(2) = srcBuf(src_row, src_col)
outBuf(3) = srcBuf(src_row, src_col + 1)
adoStream.WriteText Join$(outBuf, ",") & vbCrLf
End If
Next
Next
'
pos = pos + MAX_BUFFER_SIZE
'
'一応フリーズ対策
Application.StatusBar = "ただいま処理中... STEP " & CStr(i) & "/" & CStr(loop_count)
DoEvents
Next
'保存
adoStream.SaveToFile "C:\temp\test.csv", adSaveCreateOverWrite
adoStream.Close
Set adoStream = Nothing
Application.StatusBar = ""
MsgBox "C:\temp に CSV 書き出した☆"
End Sub
No.2
- 回答日時:
こんにちは
>20万行以上あり、毎日増え続けている状況です。
毎回ゼロから同じデータを処理しているのでしょうか?
それとも、毎回20万行が追加されるということ?
大部分が同じデータで、追加分を含めて処理しているのなら、処理済みのデータを何度も処理する手間が無駄と思います。
全体の方法を見直して、追加されたデータだけを処理すれば済むような考え方にすれば良いのではないでしょうか?
毎回、新規のデータが20万行あるような場合は、エクセルで扱うこと自体を考え直した方がよさそうにも思います。
整形したところで、人が目視で扱うようなデータ量とは思えませんので、整形すること自体の意味も疑問です。
「そんなこと聞いてないよ。 どうしてもこのままやりたいんだ!」というのであれば・・
1)どこかの3列分に、ID一つを10行分に単純にコピー参照する関数を設定
(当然、空行ができます)
2)別の列に、1)を詰めて表示する関数を設定
しておけば、何もしなくても自動で整形できます。
100万行とのことなので、時間はかかる可能性はありますが、手作業よりは速いでしょう。
ありがとうございます。
何となく仰る考え方は分かった気がするのですが以下により誤認と分かるかもしれません・・・
1) は例えば別シートに縦に並べるように参照式を設定したフォーマットを作っておく事でしょうか?
元の1行目→別シートでは10行目まで消費
元の2行目→別シートでは20行目まで消費
これを簡単に設定する方法が思い浮かびません^^;
2)については、詰めて表示する関数が分からないので教えてください。
しかし1)で20万行が200万行に膨れ上がってしまうから、最後に詰めるのだ
と難しくないですか?
よってマクロで空白判定しながら縦に並べる必要があるのかとぼんやり考えていました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(データベース) c言語の問題です。これを踏まえてコーディングしたいのでおしえていただきたいです。 3 2023/08/03 09:27
- 経営情報システム accessでの請求管理について 12 2022/06/11 16:20
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
- Excel(エクセル) 【条件付き書式】countifsで複数条件を満たしたセルを赤くする方法 2 2023/02/09 23:53
- Excel(エクセル) VBA でvlookup エラーなどは削除したい 8 2022/12/30 04:03
- デジタルカメラ 写真撮影可能なバーコードリーダーを探しています 2 2022/05/26 17:15
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
- 国産バイク 大型バイク カワサキz900rsに付ける ヨシムラのマフラーの質問です、 【 商 品 I D 】14 2 2023/06/27 13:43
- Excel(エクセル) エクセルでのVBA 2 2022/08/03 06:48
- Excel(エクセル) Excel 関数 vlookupなどの使い方について質問です。 シート1に品番、商品名、単価、発注条 6 2022/06/15 19:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
レコードが存在しなかった場合
-
DataGridViewの内容をDBに反映...
-
DataGridViewの、選択されてい...
-
差し込み印刷のレコード数について
-
ADO VBA 実行時エラー3021
-
ファイル書込みで一行もしくは...
-
ACCESSで大量の更新を行うと「...
-
ワードの差込印刷で教えて下さ...
-
レコードセット(ADO.Recordset)...
-
固有レコード識別子の選択とは
-
VB6.0のIsNull関数に相当するもの
-
サブレンジ分割されたNDB(富士...
-
DataGridViewにてセル以外をク...
-
ADOでエクセルからアクセス...
-
[VBA] ADOの Clone と AddNew
-
カレントレコードが無い事を判...
-
サブフォームに新規レコードを...
-
vb.netのdatatableのレコード削...
-
ACCESSのフォームで複数レコー...
-
ADODBのRecordset.Deleteのエラ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DataGridViewの、選択されてい...
-
カレントレコードが無い事を判...
-
レコードが存在しなかった場合
-
差し込み印刷のレコード数について
-
アクセスでレポートの1印刷内...
-
ADO VBA 実行時エラー3021
-
レコードセット(ADO.Recordset)...
-
ACCESSで大量の更新を行うと「...
-
ファイル書込みで一行もしくは...
-
JSPのNULLレコード表示について...
-
ワードの差込印刷で教えて下さ...
-
固有レコード識別子の選択とは
-
データセットのレコード更新が...
-
DataGridViewの内容をDBに反映...
-
Access でレコードセレクタが押...
-
[VBA] ADOの Clone と AddNew
-
サブフォームに新規レコードを...
-
Access を×ボタンで閉じ...
-
ADODBのRecordset.Deleteのエラ...
-
サブレンジ分割されたNDB(富士...
おすすめ情報
皆さま、回答ありがとうございます。
現在、以下の方法で解決できるようにはなりました(まだ満足ではないのですが)
https://hamachan.info/excel2019-powerquery-seikei/
簡単にいうと、元CSVをPowerQueryエディタに取り込んでから以下の手順です。
(1)商品名と型番を、「カンマ区切りでマージ」※1商品を1列化できる
(2)ピボット解除で、全行にIDが付いた状態で縦並びに出来る
(3)カンマで列分割※これで(1)のように1商品2列形式に戻る。
(4)フィルタで空白を無くしてからシートに読み込む※これで100万行以内に収まる。
実際には、80万行位になりました。
しかし新しいCSVで更新をかけると約50分かかるのだけが不安要素です。
待てば完成するというという意味では解決ですが、もっと早くする方法があったら嬉しいです。