Excel VBA質問箱 IV

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

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


4518 / 13644 ツリー ←次へ | 前へ→

【55989】行単位の比較方法 74 08/5/28(水) 20:41 質問[未読]
【55991】Re:行単位の比較方法 74 08/5/28(水) 21:20 発言[未読]
【56014】Re:行単位の比較方法 Abebobo 08/5/29(木) 17:18 発言[未読]
【56018】Re:行単位の比較方法 74 08/5/29(木) 18:11 回答[未読]
【56021】Re:行単位の比較方法 Abebobo 08/5/29(木) 19:39 発言[未読]
【56024】Re:行単位の比較方法 74 08/5/29(木) 20:34 お礼[未読]
【56027】Re:行単位の比較方法 Abebobo 08/5/29(木) 21:30 発言[未読]
【56046】Re:行単位の比較方法 74 08/5/30(金) 13:16 お礼[未読]
【56048】Re:行単位の比較方法 Abebobo 08/5/30(金) 13:45 発言[未読]
【56101】Re:行単位の比較方法 n 08/6/2(月) 0:37 発言[未読]
【56103】Re:行単位の比較方法 74 08/6/2(月) 9:18 お礼[未読]
【56105】Re:行単位の比較方法 Abebobo 08/6/2(月) 11:01 発言[未読]
【56150】Re:行単位の比較方法 n 08/6/5(木) 14:37 発言[未読]
【56154】Re:行単位の比較方法 Abebobo 08/6/5(木) 20:20 発言[未読]
【56108】Re:行単位の比較方法 Yuki 08/6/2(月) 11:22 発言[未読]
【56109】Re:行単位の比較方法 kanabun 08/6/2(月) 19:06 発言[未読]
【56113】Re:行単位の比較方法 74 08/6/3(火) 10:36 お礼[未読]
【56115】Re:行単位の比較方法 kanabun 08/6/3(火) 12:43 発言[未読]
【56139】Re:行単位の比較方法 74 08/6/4(水) 12:02 お礼[未読]

【55989】行単位の比較方法
質問  74  - 08/5/28(水) 20:41 -

引用なし
パスワード
   こんばんは。

異なるシートで行単位の比較を行いたいのですが、
良い方法があればご教授願いたく思っております。

イメージとしては下記のようになります。
(これだとエラーがでますが。。)

例)
If Worksheets("A").Rows(myRB).Value = Worksheets("B").Rows(myRA).Value Then

※Rows().Valueには半角スペース区切りの文字列が格納されているようです。
(配列ではないようです)


よろしくお願いいたします。

【55991】Re:行単位の比較方法
発言  74  - 08/5/28(水) 21:20 -

引用なし
パスワード
   すみません。
半角スペース区切りではなく、タブ区切りでしたね。
失礼いたしました。。

【56014】Re:行単位の比較方法
発言  Abebobo  - 08/5/29(木) 17:18 -

引用なし
パスワード
   レスがつかないようなので、ちょっと書いてみました。

myRB の型が書いていなのもあってレスが付きづらいのでは。
AのSheet と BのSheet の5行目を比較してみました。

Sub hikaku()
Dim myRB  As Long
Dim i   As Long
Dim fL   As Long
 
myRB = Worksheets("A").Cells(5, Columns.Count).End(xlToLeft).Column
fL = 0
For i = 1 To myRB
  If Worksheets("A").Cells(5, i).Value <> Worksheets("B").Cells(5, i).Value Then
    fL = fL + 1
  End If
Next i
MsgBox fL & " 個のセルが違う"
End Sub

【56018】Re:行単位の比較方法
回答  74  - 08/5/29(木) 18:11 -

引用なし
パスワード
   ▼Abebobo さん:
レスありがとうございます。
参考にさせていただきます。

myRAにはAシートの行No、myRBにはBシートの行Noが入るので、Longで宣言しています。

やりたいことは表の差分チェックで、
Aシートの1行目と完全フェッチする行がBシートになければ、
(=すべてのセルが同一でなければ)
それを差分として、その行がそのままCシートに抽出されるといったものになります。

よろしくお願いします。

【56021】Re:行単位の比較方法
発言  Abebobo  - 08/5/29(木) 19:39 -

引用なし
パスワード
   74さん こんにちは
ぅう〜んん・・・ ちょっと解りにくい・・・
すみません。やりたい事はわかったんですが、やる意味が解りません
なので、私が設定します。

Aシートの1行目に照合させたいデータが、A1〜J1まで10ヶ有ります。
BシートのA列にデータNo.が通し番号で振ってあり、 B列〜K列までデータが10ヶ有ります。
Bシートデータの行数は100前後で一定ではありません。

AシートのA1〜J1までのデータと、BシートのB列〜K列を比較して全てのデータが一致したときだけ、BシートA列の通しNo.と、B列〜K列までのデータを、Cシートに上から順番に転機します。
*1.そして、Aシートのデータと、全て一致する、Bシートの 通しNo. を検出します。

Sub hikaku()
Dim myRB  As Long
Dim ShB_lr As Long
Dim ShC_lr As Long
Dim i   As Long
Dim ii   As Long
 
myRB = Worksheets("A").Cells(1, Columns.Count).End(xlToLeft).Column
'↑ 私の設定では 10 になるはず。
ShB_lr = Worksheets("B").Cells(Rows.Count, 1).End(xlUp).Row
'↑ 私の設定では 100前後。
ShC_lr = Worksheets("C").Cells(Rows.Count, 1).End(xlUp).Row

For ii = 1 To ShB_lr
  For i = 1 To myRB
    If Worksheets("A").Cells(1, i).Value <> Worksheets("B").Cells(ii, i + 1).Value Then GoTo Bobo
  Next i
  Worksheets("C").Cells(ShC_lr, 1).Resize(, myRB + 1).Value = _
            Worksheets("B").Cells(ii, 1).Resize(, myRB + 1).Value
  ShC_lr = ShC_lr + 1

Bobo:
Next ii
End Sub

注1.が不必要でシートレイアウトがそうじゃなかったら、コードの中の +1 を全部消して使ってください。

Ps.
>Aシートの1行目と完全フェッチする行がBシートになければ
完全フェッチ って? なんかいやらしい言葉?(な〜んちゃって) ←久しぶり使った

コードの説明は、家についてから書きます。

【56024】Re:行単位の比較方法
お礼  74  - 08/5/29(木) 20:34 -

引用なし
パスワード
   ▼Abebobo さん:
たびたびありがとうございます。
参考にしてがんばってみます。
また説明不足ですみませんです。。

目的は、異なる環境の同一テーブルデータの差分をEXCELに抽出するためとなります。

たとえば、

<Aシート>   <Bシート>
1 田中 男  1 田中 女 
2 鈴木 女  2 鈴木 女
3 高橋 男  3 高橋 男
        4 加藤 男

とあった場合、Cシートには下記のように抽出したいのです。

<Cシート>
1 田中 女
4 加藤 男

A,Bシートは同じテンプレートで、行数またはセルの値のみ異なります。

また、このマクロは他テーブルにも汎用的に使用したいため、
キー項目による比較はできず、1つでもセル値がことなる場合も抽出したいのです。

よろしくお願いします。

【56027】Re:行単位の比較方法
発言  Abebobo  - 08/5/29(木) 21:30 -

引用なし
パスワード
   74 さぁ〜ん 最初からそ〜いう風にせつめーしてくださいよ〜 
なんてね (^-^)

ならば、私のコードの2つのForをくくる感じでForを増やせばできます。

コードの説明は、

Bシートに名を連ねた挑戦者たちが、自分に書かれた情報どおりに、黒ひげ危機一髪に挑んだ!。ひとつでも間違えたとたん、その挑戦者は失格退場!! そしてまた、次の挑戦者が黒ひげ危機一髪に挑んでいく。すべての剣を刺す事のできた挑戦者のみが、Cシートに殿堂入りできるんだ。 

で、74さんが今から私のコードを改造するなら、
Aシートにを連ねた挑戦者たちが、Bシートに並んだコースを走るんだ。
一つのコースには落とし穴がいくつも開いている。自分が持っている色んな形のふたがすべての落とし穴の形に合えば、ゴールまでたどり着く事ができる。ゴールにたどり着いたらCシートでチョメチョメできるんだ。 一つのコースで失敗しても心配するな! さあ次のコースでがんばろう。

というイメージでコードを書けば・・・。

コードを書くより、私の説明の解読の方が難しい??

【56046】Re:行単位の比較方法
お礼  74  - 08/5/30(金) 13:16 -

引用なし
パスワード
   Abeboboさん

どうもありがとうございました!
いただいたコードを元に無事うまくいきました。

結局、配列等を使用しても「if A行=B行 then」のような一発では比較はできないってことなのでしょうか?

一番最初にSPLITやJOINを使用して試みたのですが、
うまくいかなかったものでして。。

いづれにせよ、このたびはありがとうございました。

【56048】Re:行単位の比較方法
発言  Abebobo  - 08/5/30(金) 13:45 -

引用なし
パスワード
   74 さんこんにちは

>結局、配列等を使用しても「if A行=B行 then」のような一発では比較はできないってことなのでしょうか?

私も同じこと思ったんですよ! Range("A1:C5").value=Range("A10:C15).value  が出来るんだから出来るはずだと思ったんですけど...。 

【56101】Re:行単位の比較方法
発言  n  - 08/6/2(月) 0:37 -

引用なし
パスワード
   こんにちは。

例えばですが
Dim v, w

v = Range("A1").Resize(10, 10).Value
w = Range("K1").Resize(10, 10).Value
With Application
  Debug.Print Join(.Index(v, 1, 0)) = Join(.Index(w, 1, 0))
End With
こんな感じや、

'参照設定:Microsoft Forms 2.0 Object Library
Dim s1() As String
Dim s2() As String

Range("A1").Resize(10, 10).Copy
With New DataObject
  .GetFromClipboard
  s1 = Split(.GetText, vbCrLf)
  Range("K1").Resize(10, 10).Copy
  .GetFromClipboard
  s2 = Split(.GetText, vbCrLf)
End With
Application.CutCopyMode = False
Debug.Print s1(0) = s2(0)
こんな感じとか。

#でも、配列に格納したら、素直にそれをLoop判定したほうが速そうです。

【56103】Re:行単位の比較方法
お礼  74  - 08/6/2(月) 9:18 -

引用なし
パスワード
   n さん、Abeboboさん

こんにちは。
ありがとうございます!
なるほど。。
勉強になります。

そうなんですね。
ループのほうが早いのですね。。
意外です。。

いろいろ試してみます。
このたびはありがとうございました。

【56105】Re:行単位の比較方法
発言  Abebobo  - 08/6/2(月) 11:01 -

引用なし
パスワード
   74 さん n さん、こんにちは

Join 初めて使いました。
50行程度のサンプルでは、速さの違いは実感できませんでしたが。
Loopが少ない分、メンテの時に良いのか?

Sub hikaku2()
Dim ShA_lC As Long   'Aシート最終列
Dim ShA_lr As Long   'Aシート最終行
Dim ShB_lr As Long   'Bシート最終行
Dim ShC_lr As Long   'Cシート最終行
Dim i As Long, ii As Long
Dim v As Variant, w As Variant
Dim J1 As String, J2 As String
 
ShA_lC = Worksheets("A").Cells(1, Columns.Count).End(xlToLeft).Column
ShA_lr = Worksheets("A").Cells(Rows.Count, 1).End(xlUp).Row
ShB_lr = Worksheets("B").Cells(Rows.Count, 1).End(xlUp).Row
ShC_lr = Worksheets("C").Cells(Rows.Count, 1).End(xlUp).Row

With Worksheets("A")
  For i = 1 To ShA_lr
   v = .Cells(i, 1).Resize(, ShA_lC).Value  '比較する行を配列に収納
    For ii = 1 To ShB_lr
      w = Worksheets("B").Cells(ii, 1).Resize(, ShA_lC).Value  '比較される行を配列に収納
      J1 = Join(Application.Index(v, 1, 0))  'ローカルウインドウで確認用
      J2 = Join(Application.Index(w, 1, 0))
        If J1 = J2 Then
          Worksheets("C").Cells(ShC_lr, 1).Resize(, ShA_lC).Value = _
                      .Cells(i, 1).Resize(, ShA_lC).Value
          ShC_lr = ShC_lr + 1
          GoTo A
        End If
    Next ii
A:
  Next i
End With

* nさん いつもありがとうございます。

【56108】Re:行単位の比較方法
発言  Yuki  - 08/6/2(月) 11:22 -

引用なし
パスワード
   ▼74 さん:
><Aシート>   <Bシート>
>1 田中 男  1 田中 女 
>2 鈴木 女  2 鈴木 女
>3 高橋 男  3 高橋 男
>        4 加藤 男
>
>とあった場合、Cシートには下記のように抽出したいのです。
>
><Cシート>
>1 田中 女
>4 加藤 男
>
こんにちは。
こんな方法ではどうですか。

Sub TESTa()
  Dim SD As Object
  Dim i  As Long
  Dim j  As Long
  Dim vA As Variant
  Dim vB As Variant
  Dim vC As Variant
  
  Set SD = CreateObject("Scripting.Dictionary")
  With Worksheets(1)
    vA = .Range("A1:A" & .Cells(.Rows.Count, 1).End(xlUp).Row).Value
  End With
  With Worksheets(2)
    vB = .Range("A1:A" & .Cells(.Rows.Count, 1).End(xlUp).Row).Value
  End With
  ReDim vC(1 To UBound(vB), 1 To UBound(vB, 2))
  For i = 1 To UBound(vA)
    SD(vA(i, 1)) = Empty
  Next
  
  For i = 1 To UBound(vB)
    If Not SD.Exists(vB(i, 1)) Then
      j = j + 1
      vC(j, 1) = vB(i, 1)
    End If
  Next
  Worksheets(3).Range("A1").Resize(j, 1).Value = vC
End Sub

【56109】Re:行単位の比較方法
発言  kanabun  - 08/6/2(月) 19:06 -

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

こんばんは。途中からお邪魔します。

>たとえば、
>
><Aシート>   <Bシート>
>1 田中 男  1 田中 女 
>2 鈴木 女  2 鈴木 女
>3 高橋 男  3 高橋 男
>        4 加藤 男

これは、A列に「TAB区切り」でデータが並んでいるサンプルですか?
それとも、複数列にデータが入っているサンプルなのですか?

【56113】Re:行単位の比較方法
お礼  74  - 08/6/3(火) 10:36 -

引用なし
パスワード
   >kanabunさん
こんにちは。
わかりにくくて、すみませんです。。
複数列にデータが入っているサンプルとなります。
よろしくお願いします。


>Yukiさん、Akeboboさん
ありがとうございます!
いろいろ試してみます。
勉強になります。

【56115】Re:行単位の比較方法
発言  kanabun  - 08/6/3(火) 12:43 -

引用なし
パスワード
   ▼74 さん:
> 複数列にデータが入っているサンプルとなります。

複数列を行単位で比較して
「A」にあって「B」にないものを「C」に抽出するために、
n さんと Yuki さんの方法を勝手にドッキングさせてもらいました


'参照設定:Microsoft Forms 2.0 Object Library
Sub Try3()
 Dim r1 As Range  'シートA データ範囲
 Dim r2 As Range  'シートB データ範囲
 Dim r3 As Range  'シートC 貼り付け先セル
 Dim s1() As String 'Aの各行をTAB区切りで文字列にしたもの(行数分配列)
 Dim s2() As String 'Bの各行をTAB区切りで文字列にしたもの(行数分配列)
 Dim s3() As String
 Dim i As Long
 
 Set r1 = Worksheets("A").[A1].CurrentRegion '↓「A」と列数をそろえる
 Set r2 = Worksheets("B").[A1].CurrentRegion.Resize(, r1.Columns.Count)
 With New DataObject
   r1.Copy
   .GetFromClipboard
   s1 = Split(.GetText(1), vbCrLf)
   r2.Copy
   .GetFromClipboard
   s2 = Split(.GetText(1), vbCrLf)
 End With
 Application.CutCopyMode = True
 
 With Worksheets("C")  
   .UsedRange.ClearContents    '抽出先シートのクリア
   Set r3 = .[A1]         '貼り付け先セル
 End With
 
 With CreateObject("Scripting.Dictionary")
   For i = 0 To UBound(s2)
    .Item(s2(i)) = Empty
   Next
   For i = 0 To UBound(s1)
    If Not .Exists(s1(i)) Then
      s3 = Split(s1(i), vbTab)
      r3.Resize(, UBound(s3) + 1).Value = s3
      Set r3 = r3.Offset(1)
    End If
   Next
 End With
End Sub

【56139】Re:行単位の比較方法
お礼  74  - 08/6/4(水) 12:02 -

引用なし
パスワード
   ▼kanabun さん:
ありがとうございます!
参考にさせていただきます。

皆様、本当にありがとうございました。

【56150】Re:行単位の比較方法
発言  n  - 08/6/5(木) 14:37 -

引用なし
パスワード
   ▼Abebobo さん:
蛇足でごめんなさい。
Abeboboさんのそのコードでは、INDEX関数を使うメリットが半減しています。
ワークシート関数INDEXのヘルプを参照してください。
『配列 が複数行および複数列で構成され、
 行番号 または 列番号 のどちらか一方しか指定されていない場合、
 配列 の中にある行または列全体の配列が返されます。』

Sub try()
  Dim i As Long
  Dim v, x

  v = [{11,21,31;12,22,32;13,23,33}]
  For i = 1 To 3
    x = Application.Index(v, i, 0)
    Stop
    Debug.Print Join(x)
  Next
End Sub

上記は2次元配列から各行を1次元配列で取り出す例です。
最初に配列vにまとめて格納し、後はそれをLoopすればよいです。
(今回のケースは、後でセルに戻す時の事を考えると、DataObjectを使ったほうが良いとは思いますが)

【56154】Re:行単位の比較方法
発言  Abebobo  - 08/6/5(木) 20:20 -

引用なし
パスワード
   n さん
いつもありがとうございます。
>ワークシート関数INDEXのヘルプを参照してください。
やっぱり一般機能と一緒でよかったんですね。
VBAのヘルプには載っていませんでした。

>Stop
これ、いいですね〜。nさんにローカルウインドウを教えていただいてから、ずっとブレイクで確認していました。

ほかの方のスレですので準備出来次第、別でスレたたせていただきます。
そのときはよろしくお願いします。

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