- ベストアンサー
エクセルVBA(値または文字の重複削除)
先日まで何も出来ない状態でしたが、時間が出来たので、 またVBAを触り始めました。 質問はVBAで変数に代入されている値または文字の重複を削除したいのです。 セル範囲を取得し、変数に代入するまではいいのですが、 行列にまたがって範囲選択すると複数のセル位置(数値)が入ってしまいます。 例えば、D8からE9とD12からD13まで選択すると、変数の「セル位置」には「$D$8$E$8$D$9$E$9$D$12$D$13」が代入されますが、 $D$8=$E$8 $D$9=$E$9 数値の部分(内部は文字列ですが)が重なってしまいます。 これを、「$D$8$E$$D$9$E$$D$12$D$13」など数値(文字)のどちらかを削除出来ないものかと悩んでいます。 利用するのは数字の部分だけなので、その処理自体は問題ありません。 IF文でループさせて文字が存在するか見ているだけです。 また、比較自体も必ず偶数行だけですので、最後の「$」が無くても問題はありません。 For 始まり行 = セル開始行 To 入力行数 Step 2 If InStr(セル位置, "$" & Trim(始まり行) & "$") Then Exit For End If Next ただ、重複があるとそれも個数に含まれてしまい、計算がおかしくなります。 選択セル範囲の個数取得にはRange.Addressを使っています。 Dim rg As Range 'セル セル位置 = "" For Each rg In Selection セル位置 = セル位置 + rg.Address Next 縦1列なら大丈夫なのですが、複数列になると問題になります。 列行関係なく選択されたセルの行数が分かればいいだけなんですが・・・ 考え方だけでも構いませんので、よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>縦1列なら大丈夫なのですが、複数列になると問題になります。 >列行関係なく選択されたセルの行数が分かればいいだけなんですが・・・ たぶん、「Rows.Count」を使えばできそうだったと思います。 手元にExcelが無いため、参考意見として述べます。 「Selection.Areas」のプロパティだったような記憶があります。 何かのヒントになればと思います、書き込みます。 (Webで検索しましたが、情報をみつけられませんでした。) ■(複数の)選択した範囲の個数の取得 Selection.Areas.Count ※D8からE9の選択なら「1」。 D8からE9とD12からD13まで選択すると「2」のはずです。 ■(複数の)選択した範囲の行数の取得。 Selection.Areas(i).Rows.Count 例)D8からE9とD12からD13まで選択したとき Selection.Areas(1).Rows.Count が「2」 Selection.Areas(2).Rows.Count が「2」を返す。 こんな感じだったと思います。 これらをFORで繰り返して、足し合わせれば、離れた 選択範囲の行数が取得できたと思います。 以下のような感じだと思いますが、かなりあてずっぽうです。 Dim cntRow as Integer '行数のカウント※型名「Integer」は正しいでしょうか? cntRow = 0 Dim I as Integer FOR I = 1 To Selection.Areas.Count cntRow = cntRow + Selection.Areas(I).Rows.Count Next 詳細はExcelのヘルプにて、「Areas」のメソッドとプロパティを 確認してみてください。 てきとうな回答ですみません・・・
その他の回答 (1)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 質問の時は、目的をはっきりと示してくださいね。 あれこれ、自分の考えのプロセスの中で質問を言われたら、それを全部考えなくてはならなくなります。(そういう義務はありませんが(^^;) >例えば、D8からE9とD12からD13まで選択すると、 >変数の「セル位置」には「$D$8$E$8$D$9$E$9$D$12$D$13」が代入されますが、 Sub Test1() '範囲を選択すると Dim r As Range Set r = Union(Range("D8:E9"), Range("D12:D13")) MsgBox r.Address(0, 0) 'D8:E9,D12:D13 と出力します。 End Sub 仮に、Selection でとっても、まったく同じです。 Sub Test2() 'マウスで選択 MsgBox Selection.Address(0, 0) 'D8:E9,D12:D13 と出力します。 End Sub >行列にまたがって範囲選択すると複数のセル位置(数値)が入ってしまいます。 Sub Test3() '選択セル範囲の個数取得 Dim r As Range Set r = Union(Range("D8:E9"), Range("D12:D13")) MsgBox "セルの数は、" & r.Count & " 個です。" End Sub >縦1列なら大丈夫なのですが、複数列になると問題になります。 >列行関係なく選択されたセルの行数が分かればいいだけなんですが・・・ Sub Test4() '列行関係なく選択されたセルの行数 Dim myArea As Range Dim a As Range Set myArea = Union(Range("D8:E9"), Range("D12:D13")) '行 Set a = Intersect(myArea.Cells(1).EntireColumn, myArea) MsgBox a.Cells.Count & "行です。" End Sub >これを、「$D$8$E$$D$9$E$$D$12$D$13」など数値(文字)のどちらかを削除出来ないものかと悩んでいます。 Sub Test5() Dim buf As String Dim Alph As String Dim Num As String Dim T As String Const TXT = "$D$8$E$$D$9$E$$D$12$D$13" '数値(文字)のどちらかを削除 buf = Replace(TXT, "$", "") For i = 1 To Len(buf) T = Mid$(buf, i, 1) If T Like "*[A-Z]*" Then Alph = Alph & T ElseIf T Like "*[0-9]*" Then Num = Num & T End If Next i MsgBox "数字: " & Num & vbCr & _ "文字: " & Alph End Sub
お礼
>質問の時は、目的をはっきりと示してくださいね。 申し訳ありません。 自分なりに考えて目的を書いたつもりなんですが・・・ 正規表現は全く理解できないので何とも云えませんが、 少々、ニュアンスが違っています。 「Num」には数字文字だけが抽出されてしまうんですね。 「$」はそのままで、重複する数値だけを削除したかったのです。 参考にさせて頂きます。 ありがとうございました。
お礼
行数取得出来ました。 仕事が優先なので、途中で止まっていました。 コーディングしている内に、行数だけでは問題がある事が分かりました。 しかし、Areas.Countは参考になりました ループごとに選択範囲セルの行数が取得出来るのですね。 これは便利です。 ありがとうございました。