Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


728 / 13645 ツリー ←次へ | 前へ→

【78679】よろしくお願いいたします。 斉藤 16/12/16(金) 22:12 質問[未読]
【78680】Re:よろしくお願いいたします。 β 16/12/16(金) 23:37 発言[未読]
【78681】Re:よろしくお願いいたします。 β 16/12/16(金) 23:52 発言[未読]
【78682】Re:よろしくお願いいたします。 斉藤 16/12/17(土) 1:28 発言[未読]
【78683】Re:よろしくお願いいたします。 β 16/12/17(土) 6:48 発言[未読]
【78684】Re:よろしくお願いいたします。 β 16/12/17(土) 7:06 発言[未読]
【78685】Re:よろしくお願いいたします。 β 16/12/17(土) 7:41 発言[未読]
【78688】Re:よろしくお願いいたします。 斉藤 16/12/17(土) 10:11 回答[未読]
【78692】Re:よろしくお願いいたします。 斉藤 16/12/17(土) 11:47 質問[未読]
【78694】Re:よろしくお願いいたします。 β 16/12/17(土) 13:15 発言[未読]
【78695】Re:よろしくお願いいたします。 斎藤 16/12/18(日) 17:13 質問[未読]
【78696】Re:よろしくお願いいたします。 β 16/12/18(日) 19:43 発言[未読]
【78697】Re:よろしくお願いいたします。 斉藤 16/12/18(日) 20:00 発言[未読]
【78698】Re:よろしくお願いいたします。 β 16/12/18(日) 20:03 発言[未読]
【78699】Re:よろしくお願いいたします。 β 16/12/18(日) 20:12 発言[未読]
【78700】Re:よろしくお願いいたします。 β 16/12/18(日) 20:20 発言[未読]
【78703】Re:よろしくお願いいたします。 斎藤 16/12/19(月) 23:26 お礼[未読]

【78679】よろしくお願いいたします。
質問  斉藤 E-MAIL  - 16/12/16(金) 22:12 -

引用なし
パスワード
   お世話になります。
会社でとあるデータを扱っているのですが、手処理が大変なのでなんとかしたいと考えています。

A〜Qまでの列に各項目があり、全体で8000件弱のデータがあります。
1行目は見出しとなっています。

A列に6桁の番号があり、ソートされていない状態で、また部分的に重複があります。
重複は無いものもありますが、多いと10件以上重複しています。
重複しているデータのA〜Pまでの列の情報は、すべて同じ情報です。

Q列には文字列があるので、重複しているデータはQ列のみカンマ区切りで結合し、
重複のない状態でこれを別のシートに、1行目は見出し付で表示させたいと思っています。

VBAで処理したいと考えていますが、結合の辺りで分からなくて途方に暮れています。
お助け頂けると、本当に助かります。
どうかよろしくお願い致します!

【78680】Re:よろしくお願いいたします。
発言  β  - 16/12/16(金) 23:37 -

引用なし
パスワード
   ▼斉藤 さん:

サロンはマルチ禁止しています。
質問箱のほうは許容していますが、差異との基本方針がありますので
熟読し、次回からは気を付けてください。

一例です。

Sub Sample()
  Dim c As Range
  Dim dic1 As Object
  Dim dic2 As Object
  
  Set dic1 = CreateObject("Scripting.Dictionary")
  Set dic2 = CreateObject("Scripting.Dictionary")
  
  With Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic1.exists(c.Value) Then
        dic1(c.Value) = c.EntireRow.Range("A1:P1").Value
        dic2(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic2(c.Value) = dic2(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
  
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1:P1").Resize(dic1.Count).Value = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic1.items))
    .Range("Q1").Resize(dic2.Count).Value = WorksheetFunction.Transpose(dic2.items)
    .Select
  End With
  
End Sub

【78681】Re:よろしくお願いいたします。
発言  β  - 16/12/16(金) 23:52 -

引用なし
パスワード
   ▼斉藤 さん:

もう一例、A〜Pを重複の削除機能で処理するパターンです。
8000件ぐらいなら、アップ済みのものとあまり効率はかわらないと思いますが。

Sub Sample2()
  Dim c As Range
  Dim dic As Object
  Dim v As Variant
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("Sheet1")
    v = .Range("A1").CurrentRegion.Columns("A:P").Value
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic.exists(c.Value) Then
        dic(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic(c.Value) = dic(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
  
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1").Resize(UBound(v, 1), UBound(v, 2)).Value = v
    .Columns("A:P").RemoveDuplicates Columns:=1, Header:=xlYes
    .Range("Q1").Resize(dic.Count).Value = WorksheetFunction.Transpose(dic.items)
    .Select
  End With
End Sub

【78682】Re:よろしくお願いいたします。
発言  斉藤 E-MAIL  - 16/12/17(土) 1:28 -

引用なし
パスワード
   ▼β さん:

始めまして。
斉藤です。
このたびは2パターンも作って下さりありがとうございます!
なお、ルールに抵触してしまいました事、お詫び申し上げます。

会社のExcelは2013に対して、自宅のは古く2002を使っているのが原因だと思いますが・・・。

パターン1は、実行すると「型が一致しません。」とエラーとなり、
新しく作られたシートでは、A〜Pまで重複行は1本にまとめられていますが、
Q列が空白となっています。

パターン2は、実行すると「オブジェクトは、このプロパティまたはメゾットをサポートしていません。」とエラーとなり、新しく作られたシートではA〜Pは
表示されていますが、重複行は残ったままとなっており、またQ列も1と同様に
同じく空白となっています。

Q列のセルを確認しましたところ、2002では「標準」となっておりました。

引き続き、サポート頂けると助かります。

【78683】Re:よろしくお願いいたします。
発言  β  - 16/12/17(土) 6:48 -

引用なし
パスワード
   ▼斉藤 さん:

xl2002ですか。
こちらにはその環境がないので確認はできないのですが、

・Sampleのほう、エラーは、
Range("Q1").Resize(dic2.Count).Value = WorksheetFunction.Transpose(dic2.items)

ここで発生したんですね。
う・・・ん、ちょっと調べてみますが、会社の xl2013 で処理するとどうなるか
教えてくださいね。

・Sample2 のほうは原因が明確です。

 .Columns("A:P").RemoveDuplicates Columns:=1, Header:=xlYes

これは xl2007で、初めてリリースされた機能ですので。
xl2002 であれば、これにかわるというか、代替手段として AdvancedFilter がありますけど
ここを AdvancedFilterに変更したとしても、その下に、Sampleでエラーになったコードと同じものがありますので。

これも会社の xl2013 で試してください。

【78684】Re:よろしくお願いいたします。
発言  β  - 16/12/17(土) 7:06 -

引用なし
パスワード
   ▼斉藤 さん:

とりあえず Sample2 のほうの 重複の削除を AdvancedFilter に変更したものを。
xl2002 のAdvancedFilter(フィルターオプション)は、それ以前の xl2000 や
それ以降の xl2003等 とは、少し機能が異なる部分がありますので、どうなるか
わかりませんが。
でも、これでも、その下のコードで Sample と同じエラーになるはずです。

Sub Sample3()
  Dim c As Range
  Dim dic As Object
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic.exists(c.Value) Then
        dic(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic(c.Value) = dic(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
 
  With Sheets("Sheet2")
    .Cells.ClearContents
    Sheets("Sheet1").Columns("A:P").AdvancedFilter Action:=xlFilterCopy, _
      CopyToRange:=.Range("A1"), Unique:=True
    .Range("Q1").Resize(dic.Count).Value = WorksheetFunction.Transpose(dic.items)
    .Select
  End With
  
End Sub

【78685】Re:よろしくお願いいたします。
発言  β  - 16/12/17(土) 7:41 -

引用なし
パスワード
   ▼斉藤 さん:

サロンのほうはマルチ禁止ですし、質問箱のルールでも 禁止しているサイトとのマルチはだめとなっていますので
サロンのほうに、質問取り下げの旨、コメントを入れ、解決マークをチェックして閉じておいてくださいね。

【78688】Re:よろしくお願いいたします。
回答  斉藤 E-MAIL  - 16/12/17(土) 10:11 -

引用なし
パスワード
   ▼β さん:

β さん、おはようございます。
sample3のプログラム本当にありがとうございました!
マルチで投稿していた質問は取り下げさせて頂きました。

sample3の動作は重複行の削除は実行でき、エラーはsample1と同様、Q列は表示されていない状況となりました。

2002の環境で実施する訳ではないので、本日、インターネットカフェなど別環境でsample1〜3の動作確認を実施したいと思います。
それが動けば何の問題もないので、今の環境下の問題に関しては特にお調べ頂かなくて結構です。

引き続き、よろしくお願い致します!

【78692】Re:よろしくお願いいたします。
質問  斉藤 E-MAIL  - 16/12/17(土) 11:47 -

引用なし
パスワード
   2002環境下で実ファイルで実行してみたところ、本当に申し訳ないのですが新たな問題が見つかりました。

現在のファイルには、「33Q10000000ttAp」というsheet名が付いており、他のシートは存在しない状態になっています。

実ファイルの方で実行すると、sheet2が無いためか「インデックスが有効範囲にありません」とエラーが表示されました。
そのため「result」というシートを作ってから、「result」sheetに結果を表示させるようにしたいのですが、ご教授頂けますでしょうか?

【78694】Re:よろしくお願いいたします。
発言  β  - 16/12/17(土) 13:15 -

引用なし
パスワード
   ▼斉藤 さん:

アップしたコード、いずれもサンプルとして、
元シート名が "Sheet1"、転記シート名が "Sheet2" となっています。

なので、それぞれのシート名を実際のものに変更すればOKです。

転記シートですが、マクロで動的に作りだすということはもちろんできますが
とりあえずは最初から用意しておいてください。

存在しない場合は動的に作りだしたいということであれば、現在のコードが
ちゃんとxl2013で動くことを確認してから追加しますので。

なお、Sample3 ですけど、A〜P のすべての列の値で重複削除をしています。
A列が同じなら B〜P も同じということなら問題ないですが、万が一、そうではないデータがあれば
結果はおかしくなりますので。

【78695】Re:よろしくお願いいたします。
質問  斎藤 E-MAIL  - 16/12/18(日) 17:13 -

引用なし
パスワード
   ▼β さん:

お世話になります。
本日近所の環境を探したところ、EXCEL2007以上が見つからず、やむを得ず先に2007で確認いたしました。
結果から申し上げますと、頂いたsample1と3は「型が一致しません」というエラー表示がされ、Q列は表示されませんでした。
また、マシンパワーを相当食うようで2分程度処理に時間が掛っており、sample2は固まってしまいました。

元シート名をリネームし "Sheet1"、転記シート名を追加し "Sheet2" して実施いたしました。


私のお願いしたやり方では時間が掛るのかなと思いますので、生意気を言って申し訳ありませんが…以下のような形にできますでしょうか?

1. 作業シートSheet2を作成→A列を参照して若番から順にソートしていただき、転記。A列でソートされた形でA〜Qまでが並びます。

2. 作業シートSheet2を、重複のある行をQ列のみ処理をしていくのですが、重複行1行目のQ以降にQ,重複行2行目は重複行1行目のR,重複行3行目は重複行1行目のS,…T,U,V…などという形で転記します。

3. R以降のセルがある場合にはQ列に結合(Q列にデータの存在しないものもあります。)→A列の重複行を削除という流れになるとシンプルになるのではないかな?と思っています。(作業シートで処理を進めて頂いても構いませんし、resultsシートに結果表示させて頂いても構いません。)

もちろん明日以降に2013にてsample1〜3を試させて頂きますが、できますならばご検討下さい。

【78696】Re:よろしくお願いいたします。
発言  β  - 16/12/18(日) 19:43 -

引用なし
パスワード
   ▼斎藤 さん:

>やむを得ず先に2007で確認いたしました。

2007があったということですか?
で、2007でもNGだったということですか?

2002 の間違いでしょうか。

もちろん、こちらでは、いくつかのパターンを想定して、動かしていますが
どのコードも、それぞれのパターンに対して正常に処理されています。

ですので、会社の 2013 による検証、よろしくお願いしますね。

>また、マシンパワーを相当食うようで2分程度処理に時間が掛っており、sample2は固まってしまいました。

たかだか8000件であれば、瞬時に終了するはずです。
何か、別の原因があると思いますねぇ。

>私のお願いしたやり方では時間が掛るのかなと思いますので、生意気を言って申し訳ありませんが…以下のような形にできますでしょうか?

う〜ん・・・
どうしても ということなら、コードを書きますけど、会社のxl2013で検証した後ということでは
遅すぎる、もっと早くコードがほしいということですか?

【78697】Re:よろしくお願いいたします。
発言  斉藤 E-MAIL  - 16/12/18(日) 20:00 -

引用なし
パスワード
   ▼β さん:

本当に何度も申し訳ありません。
今回はEXCEL2007を使用させて頂きました。

> ですので、会社の 2013 による検証、よろしくお願いしますね

承知致しました。
砂時計となり、処理を繰り返しているようです。

ただ、まずは2013で動作検証してからで、報告させていただきますので、それからで結構です。

引き続きよろしくお願い致します。

【78698】Re:よろしくお願いいたします。
発言  β  - 16/12/18(日) 20:03 -

引用なし
パスワード
   ▼斉藤 さん:

こちらで、今、パターンを変えて実行すると、型が一致しないというエラーが再現しました。
偉そうにいっていましたが、どこかにバグがあるわけですね。

調べま〜す。(ごめんなさい)

【78699】Re:よろしくお願いいたします。
発言  β  - 16/12/18(日) 20:12 -

引用なし
パスワード
   ▼斉藤 さん:

原因がわかったようです。
今までのテストパターンでは Q列の文字列連結結果の桁数が小さかったのですが
これを、元データの桁数を長くし、かつ、A列が同じものをたくさん作って実行。
結果、Q列の文字数が長くなって、これは、そのままセットすれば問題がないのですが
Transposeを掛けたとき、その制限に引っかかったようです。

Sample1,2,3 とも、そのエラー対応をした上で、後ほどアップします。

【78700】Re:よろしくお願いいたします。
発言  β  - 16/12/18(日) 20:20 -

引用なし
パスワード
   ▼斉藤 さん:

迷惑かけました。
改訂版です。お試しください。

Transpose 要素数の制限は認識していましたが、要素内の文字の桁数制限は
はじめて認識しました。

勉強になりました。

Sub Sample()
  Dim c As Range
  Dim dic1 As Object
  Dim dic2 As Object
  Dim w As Variant
  Dim v As Variant
  Dim x As Long
  
  Set dic1 = CreateObject("Scripting.Dictionary")
  Set dic2 = CreateObject("Scripting.Dictionary")
 
  With Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic1.exists(c.Value) Then
        dic1(c.Value) = c.EntireRow.Range("A1:P1").Value
        dic2(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic2(c.Value) = dic2(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
 
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1:P1").Resize(dic1.Count).Value = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic1.items))
    w = dic2.items
    ReDim v(0 To UBound(w, 1), 1 To 1)
    For x = 0 To UBound(w, 1)
      v(x, 1) = w(x)
    Next
    .Range("Q1").Resize(dic2.Count).Value = v
    .Select
  End With
 
End Sub

Sub Sample2()
  Dim c As Range
  Dim dic As Object
  Dim v As Variant
  Dim w As Variant
  Dim x As Long
  
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("Sheet1")
    v = .Range("A1").CurrentRegion.Columns("A:P").Value
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic.exists(c.Value) Then
        dic(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic(c.Value) = dic(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
 
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1").Resize(UBound(v, 1), UBound(v, 2)).Value = v
    .Columns("A:P").RemoveDuplicates Columns:=1, Header:=xlYes
    w = dic.items
    ReDim v(0 To UBound(w, 1), 1 To 1)
    For x = 0 To UBound(w, 1)
      v(x, 1) = w(x)
    Next
    .Range("Q1").Resize(dic.Count).Value = v
    .Select
  End With
End Sub

Sub Sample3()
  Dim c As Range
  Dim dic As Object
  Dim w As Variant
  Dim v As Variant
  Dim x As Long
  
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
      If Not dic.exists(c.Value) Then
        dic(c.Value) = c.EntireRow.Range("Q1").Value
      Else
        dic(c.Value) = dic(c.Value) & "," & c.EntireRow.Range("Q1").Value
      End If
    Next
  End With
 
  With Sheets("Sheet2")
    .Cells.ClearContents
    Sheets("Sheet1").Columns("A:P").AdvancedFilter Action:=xlFilterCopy, _
      CopyToRange:=.Range("A1"), Unique:=True
    w = dic.items
    ReDim v(0 To UBound(w, 1), 1 To 1)
    For x = 0 To UBound(w, 1)
      v(x, 1) = w(x)
    Next
    .Range("Q1").Resize(dic.Count).Value = v
    .Select
  End With
  
End Sub

【78703】Re:よろしくお願いいたします。
お礼  斎藤  - 16/12/19(月) 23:26 -

引用なし
パスワード
   こんばんは。
遅くなりまして、申し訳ありません。

2013で確認したところ、sample3が問題なく動作しました。
こちらを使用させていただきます。
sheet名については、手間ではないためこのまま行かせていただきます。
最後までお付き合い下さり、感謝しております。
この度は本当にお世話になりました。

728 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free