アプリ版:「スタンプのみでお礼する」機能のリリースについて

Sub Sample()
Dim i As Long
With Range("B:B")
For i = .CurrentRegion.Rows.Count To 1 Step -1
If .Offset(i, 0) = .Offset(i - 1, 0) Then .Offset(i, 0).EntireRow.Delete
Next i
End With
End Sub

上記のマクロを実行するとエラーがでますが、どこを直せばわかりません。
一つのブックのシート全体のB列の重複データーを削除したいのですが、教えて頂けないでしょうか?

A 回答 (9件)

またまたまた登場、onlyromです。


 
>一つのブックのシート全体に適応させたい

これは2つの意味に取れますが。。。。

●例えば、各シートのB列を県名と仮定する

(1)ブック全体をひとつのシートとみなしてのダブり削除
   シート1、2、3のB列に”東京”があったら
   シート1の”東京”を残し、シート2,3の”東京”を削除する

(2)ブック全体の各シート内でのダブり削除
   シート1、2、3のB列に”東京”があっても
   各シート内ではダブっていないので、削除しない
   
たぶん(1)だと思いますが99%同じコードなので2つともアップ

(1)ブック全体をひとつのシートとみなした場合
'-------------------------------------------------
Sub TestBook()
 Dim R As Long
 Dim LastRow As Long
 Dim Sht As Worksheet
 Dim myDic

 Set myDic = CreateObject("Scripting.Dictionary")

For Each Sht In ActiveWorkbook.Worksheets
  LastRow = Sht.Cells(Rows.Count, "A").End(xlUp).Row
  For R = LastRow To 2 Step -1
    If myDic.exists(Sht.Cells(R, "B").Value) Then
      Sht.Rows(R).Delete xlShiftUp
    Else
      myDic.Add Sht.Cells(R, "B").Value, ""
    End If
  Next R
Next Sht

End Sub
'-------------------------------------------------------

(2)各シート内でのダブり削除
'-------------------------------------------------------
Sub TestSheet()
 Dim R As Long
 Dim LastRow As Long
 Dim Sht As Worksheet
 Dim myDic

 Set myDic = CreateObject("Scripting.Dictionary")

For Each Sht In ActiveWorkbook.Worksheets
  LastRow = Sht.Cells(Rows.Count, "A").End(xlUp).Row
  For R = LastRow To 2 Step -1
    If myDic.exists(Sht.Cells(R, "B").Value) Then
      Sht.Rows(R).Delete xlShiftUp
    Else
      myDic.Add Sht.Cells(R, "B").Value, ""
    End If
  Next R

  myDic.RemoveAll  '●ここだけが違う

Next Sht

End Sub
'-------------------------------------------------------

2つのコードで違いは、●印のmyDic.RemoveAllがあるかないかだけです。

また、上記のようにDictionaryオブジェクトを使うと、B列のデータは、ソートされてなくてもOKです。

新しいブックに簡単なテストデータを作成し試してください。
以上。
 

この回答への補足

ありがとうございます。
私の説明不足ですいません、回答は2のほうでした。
試しましたら正確に動きました、二つのコードの違いが

>myDic.RemoveAllがあるかないかだけです。

だけとは最初見てもわからなかったのでまだまだ勉強が足りません、
今回非常に勉強になりました、ありがとうございました。

補足日時:2009/02/19 15:36
    • good
    • 0

またまた登場、回答5、onlyromです。



>下記のサンプルを試すとエラーがでました。

いやはや、申し訳ありませぬ。
With ステートばかりに目がいってました。

>For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1

これでは最終行から1行目までになり、iが1になったときエラーが出ますので、
次のように最終行から2行目まで回すようにしなければいけませんね。
●の部分。

For i = Range("A1").CurrentRegion.Rows.Count To ●2● Step -1

'---------------------------------------------------
Sub Sample()
Dim i As Long
For i = Range("A1").CurrentRegion.Rows.Count To 2 Step -1
If Cells(i, "B").Value = Cells(i - 1, "B").Value Then
Cells(i, "B").EntireRow.Delete
End If
Next i
End Sub
'----------------------------------------------------

それから、
>サンプルに複数のシートを対応させると試しに書いてみました

この意味が分かりません。。。文章もちょと怪しいし。。(^^;;;
 

この回答への補足

ご丁寧にありがとうございました。

>それから、
>サンプルに複数のシートを対応させると試しに書いてみました

書いて頂いたサンプルコードは一つのシートだけの対応でしたので、
一つのブックのシート全体に適応させたいというのが最終目標でして
試しに書いてみましたがエラーになりどうしていいものかまいっているしだいです。

補足日時:2009/02/19 08:31
    • good
    • 0

エラーの原因は他の回答にありますので省略します。



http://officetanaka.net/excel/vba/tips/tips14.htm

上記サイトの「Sample02」のコードを参考に

Sub Sample()
Dim i As Long
With Range("B1")
For i = .CurrentRegion.Rows.Count To 1 Step -1
If .Offset(i, 0) = .Offset(i - 1, 0) Then .Offset(i, 0).EntireRow.Delete
Next i
End With
End Sub

とすればよいとは思いますが
この場合、B列がソートされている必要がありますので
少し変更して

Sub Sample()
Dim i, j As Long
With Range("B:B")
For i = 1 To .CurrentRegion.Rows.Count Step 1
With Range("B" & i)
If .Value = "" Then Exit For
For j = .CurrentRegion.Rows.Count To 1 Step -1
If .Offset(j, 0) = .Value Then .Offset(j, 0).EntireRow.Delete
Next j
End With
Next i
End With
End Sub

とすれば、B列のデータが順不同で入っていても重複分を削除できます。
但し当然ですが前者のコードより処理は遅くなりますので注意下さい。
何万行も処理しようとするとフリーズするかもしれません。
(未確認です)

この回答への補足

ありがとうございました。上記のソース確認いたしました。
あとはブックのシート全体に反映させるだけですね・・・・

補足日時:2009/02/18 19:04
    • good
    • 0

#2です。



>A列もC列もデーターはありますが、B列に重複があれば、重複しているデーターを一つ残して
>(A列とC列のデーターは保存)行ごと削除です。
もしかするとB列の重複しているデータを1個だけ表示して、あとは空白にすると
言う事ではないのでしょうか?

  A B C
1 111 aaa zzz
2 222 aaa yyy
3 333 aaa xxx
とあったら
  A B C
1 111 aaa zzz
2 222   yyy
3 333   xxx
とか?

違っていたらスル~して下さい。
    • good
    • 0

回答4にもありますが、原因は、With Range("B:B") です。



例えば、i=50 を考えてみましょう

.Offset(50,0)
 → Range("B:B").Offset(50,0)
 → Range("B1:B65536").Offset(50,0)

こうなりますので、行だけ考えると
シートの最終行65536行に50行プラスした行を指定したことになりエラー


更に今後のためにいうと、
仮に、上記でエラーの出ない許容範囲、仮に、Range("B1:B10")だとしても

With Range("B1:B10)
  IF .Offset(50,0) = .offset(49,0) then

このように複数のセルの値を比較することはできません。
ここでもエラーでます。
 
'---------------------------------------------------
Sub Sample()
 Dim i As Long
 For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1
   If Cells(i,"B").value = Cells(i-1, "B").Value Then
     Cells(i, "B").EntireRow.Delete
   End If
 Next i
End Sub
'------------------------------------------------- 
 

この回答への補足

丁寧なご説明ありがとうございます。
下記のサンプルを試すとエラーがでました。
サンプルに複数のシートを対応させると試しに書いてみましたが
エラーでした・・・難しいですね・・・

Sub Sample()
 Dim i As Long
 For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1
   If Cells(i,"B").value = Cells(i-1, "B").Value Then
     Cells(i, "B").EntireRow.Delete
   End If
 Next i
End Sub

補足日時:2009/02/18 18:03
    • good
    • 0

With Range("B:B")に対して


.Offset(i, 0)と指定している部分がまずいのだと思います。
    • good
    • 0

ご希望の動きになるかわかりませんが、


For i = .CurrentRegion.Rows.Count To 2 Step -1
If .Cells(i, 2) = .Cells(i - 1, 2) Then .Cells(i, 2).EntireRow.Delete
Next i
エラーの訂正なら、といったことでしょうか。
    • good
    • 0

B列が重複している”行”を削除するというのは、A列やC列以降にはデータがないのでしょうか?



ようはB列の重複を消す場合に、他の列が削除に関連するかどうかですけど。

しない(B列のみデータがある)ならフィルタオプションでしょうか。
http://www.eurus.dti.ne.jp/~yoneyama/Excel/filte …
とか。

この回答への補足

A列もC列もデーターはありますが、B列に重複があれば、重複しているデーターを一つ残して(A列とC列のデーターは保存)行ごと削除です。

補足日時:2009/02/18 15:51
    • good
    • 0

直接の回答ではないですが。



フィルタオプションの設定を使う
Dictionaryを使って重複無し配列を作成

などの方法で重複なしリストを作成できます。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!