• ベストアンサー

エクセル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列なら大丈夫なのですが、複数列になると問題になります。 列行関係なく選択されたセルの行数が分かればいいだけなんですが・・・ 考え方だけでも構いませんので、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

>縦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」のメソッドとプロパティを 確認してみてください。 てきとうな回答ですみません・・・

kiki_s
質問者

お礼

行数取得出来ました。 仕事が優先なので、途中で止まっていました。 コーディングしている内に、行数だけでは問題がある事が分かりました。 しかし、Areas.Countは参考になりました ループごとに選択範囲セルの行数が取得出来るのですね。 これは便利です。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。 質問の時は、目的をはっきりと示してくださいね。 あれこれ、自分の考えのプロセスの中で質問を言われたら、それを全部考えなくてはならなくなります。(そういう義務はありませんが(^^;) >例えば、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

kiki_s
質問者

お礼

>質問の時は、目的をはっきりと示してくださいね。 申し訳ありません。 自分なりに考えて目的を書いたつもりなんですが・・・ 正規表現は全く理解できないので何とも云えませんが、 少々、ニュアンスが違っています。 「Num」には数字文字だけが抽出されてしまうんですね。 「$」はそのままで、重複する数値だけを削除したかったのです。 参考にさせて頂きます。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VBA教えて下さい

    VBA初心者です やりたいこと 変数を宣言し 今開いているシート(activesheet)に for nextを使用し 列5~20を調べ 行3~5を指定し もし、5~20列の2行目のどれかに”No.8”という文字があれば(ここまでのコードは書けました) その当てはまる列の3~5行を選択し(1) 更に、(1)の下2列を選択する(2) そして、(1)と(2)を結合させる といったコードが書きたいです 考えたコード Sub test() Dim i As Long Dim j As Long With ActiveSheet For j = 5 To 20 For i = 3 To 5 If .Cells(j, 2) Like "*No.8*" Then 'ここからがわかりません End If Next i Next j End With End Sub 変な書き方なので例えを書きます A1セルにNo.8の文字があれば E1セルとF1セルを選択し 更に、E3セルとF3セルも選択し E1セルとF3まとめてセルを結合といったことがしたいです。 質問頂ければ追記しますm(ーー)m おそらくoffsetを使用して選択すると思うのですが上手く出来ませんでした 回答お願い致します

  • Excel VBAで値が重複する行を削除する

    Excel2000を使っています。 シートAに数千件のデータがあります。 シートBのE列にある文字とシートAのD列の文字が重複する場合に、シートAの重複するセルがある行を削除する(且つできれば行のデータを抜き出すVBAを作ろうと考えています。 最近VBAの初心者本をやっと理解したところで、ちんぷんかんぷんとまではいかないけど、知恵熱がでました。 仕事なので自分でなんとかすべきかと思いますが、きっかけの調べ方がまずわからない。 どなたか、解かるきっかけだけでも与えて頂けないでしょうか。とくに、別シートの値と重複する値を探す場合に何をいれるかわかればきっと道は開けると思うんですが…。 初めての質問なので、質問内容が至らなかったらもうしわけありません。

  • エクセル VBA

    エクセルVBAで以下のようなデータがあります。 D列の文字列と右隣のE列の文字列の2つが入っているものをA列から探し、見つかったセルの上にセルを追加し、E列の右隣のF列に入っている文字列を代入したいです。 どのようなプログラムになりますか?

  • EXCEL VBA 重複する値のカウント

    A列2行目列タイトルで「州名」 A列3行目よりデータがはいっています (A列データ数は数千~1万件くらい)    A                         1 2 州名 3 アラバマ                       4 あらばま                       5 NEWYORK          6 California 7 ニューヨーク 下記の様に同シートD列に重複を除いた州名、E列に重複数を表したいのですが (ひらがなとカタカナ、大文字と小文字、半角と全角の区別はせずに先にでた文字でまとめる) 早い処理の方法があれば教えていただけないでしょうか? 何卒、よろしくお願いいたします。    D     E アラバマ    2 NEWYORK   2 California    1

  • エクセル VBA セル範囲の一部解除

    rangeオブジェクト型変数にセル範囲を代入した後、一部のセルを解除したいのです。 グラフを描くためにc列とE列をデータに散布図を描こうとしてます。セル範囲の選択はrange型変数に代入しました。しかしゼロ以下の値のセルは削除したいのです。 for each c in datacell if c.value <0 then c.value="" next c 上記のようにすると目的は達しますが、ワークシート上の値も削除されてしまい、好ましくありません。良い方法はないでしょうか?

  • エクセルVBAのヒントをください

    エクセルのある列に、文字列が入っているとします。 たとえば、Aであったり、Cであったり、A,C,Fとカンマ区切りで複数の文字列(個数は不定) が入っていたりします。 このとき、一行に一つの文字列しか含まないように、カンマで区切られた文字列を展開し、 複数行に分けて格納したいと思っています。 たとえば、一番上の行のセルにA、二番目の行に「C,D,A」、三番目の行にB、四番目の行に 「E,A」と入っていたら、各行に一文字列のみ入るように、上からA、C、D、A、B、E、Aという行を 作りたいと思います。各セルに含まれる文字列の個数は不定で、規則性はありません。 基本的に、 (1)各セルに含まれているカンマの数を調べる (2)カンマの数だけ次の処理を繰り返す  ・行挿入   ・最初のカンマの位置を調べる   ・先頭からカンマまでを切り取る   ・上記の値をセルに入力  ・行挿入   ・2番目のカンマの位置を調べる   ・1番目のカンマの位置+1から2番目のカンマの位置まで切り取る   ・上記の値をセルに入力 上記をカンマの数だけ繰り返す。 といった具合にしていくのだと思いますが、このような処理をするのに はどの程度のVBAのスキルが必要ですか? 上記のヒントや、参考になるサイト、書籍があればご教授ください。

  • エクセルの数値選択で

       A   B   C   D --------------------------- 1  100   500  1000  5000    … 2   3     4     5     6     … 3   5     3     5     7     … 4   2     3     4     5     … 5   4     5     2     7     … の表があったとします。 X1のセルに数値を入力すると、その数値が100未満ならX2に3~X5に4を代入、100<=X1<500ならX2に4~X5に5を代入するなど、複数の列に対し1行目の数値を判定し2行目以下の数値を指定のセルに代入したいと思います。 4以上の複数列に対しては、どのような式を使えばいいのでしょうか。IF式を使ったのですがうまくいきません。 どなたかご教示ください。

  • VBAで、離れた複数の列に対して処理を施すには?

    VBAでマクロを組んでいたところ、問題が出てきたので質問させてください。 1.任意の列を全選択する(たとえばA列とC列という離れた列です) 2.その列の中でも、すべての行にではなく、数行にだけセル結合解除という処理を施す というマクロを組もうとしています。 しかし、全選択した列の一部の行(画像参照)にだけ処理を施す、というのができません。 1列だけ全選択→セル結合解除、というのはできるのですが、複数の列(しかも列同士が隣り合っていない)に対して処理を施すというのがうまくいかず…。 以下のようにマクロを作成してみたのですが、どこが問題になってるのでしょうか? アドバイスいただけると幸いです。 Sub test1()  Dim intX_1 As Long  Dim intX_2 As Long  Dim rg1 As Range  Dim rg2 As Range  Set rg1 = Range(CStr(ActiveWindow.RangeSelection.Address))  For Each rg2 In rg1 '選択した列のうち、2行目~最後のデータが存在する行まで処理を行う intIX_1 = 2 While rg2(intIX_1) <> "" rg2(intIX_1).MergeCells = False     intIX_1 = intIX_1 + 1 If rg2(intIX_1) = "" Then Exit For End If Wend Next End Sub

  • エクセルのマクロについて 文字列操作について

    文字列操作で困っています。 A3セル以下、A列に、04/、03/、99/。。。と文字列が入力されており、それぞれ、最初の2文字を取り出して数字に変換し、それぞれを変数 qwe1 qwe2 qwe3 ... に代入したいのです。 そのための構文が知りたいのです。 また、文字列のまま、たとえば上記の/を、変数 asd に代入するにはどうしたらよいのでしょうか? ちなみに、 Range("B3").Select ActiveCell.FormulaR1C1 = "=VALUE(MID(R[-2]C[1],1,2))" という形の構文で、一旦エクセルのセルに代入して、再度、変数に放り込む形だとうまくいくのですが、数列、数十行同じ作業を繰り返すために、for next 構文を使わないと、不便で使い物になりません。 そこで、R[-2]C[1] の部分に cells(qwe,1)を使ってもエラーが出てうまく作動しませんでした。 なお、エクセル2003、OS=XPです。 再度要約しますと、 1.文字列の一部を取り出して数字に変換し、それを変数に代入したい。 2.文字列の一部の文字を取り出して、それを変数に代入したい。 3.上記1,2を繰り返すので、その繰り返すことが出来る構文が知りたい。 以上です。 どなたか教えてください。

  • VBA エクセル2000でハイパーリンクをはる

    アクティブなワークシートの特定セル(行位置、列位置 一定)と他のワークシートの不定セル(行位置、列位置 とも、或いは、どちらか、 が変数)間にハイパーリンクをはりたい 実現したいことは至ってシンプルでセル間をジャンプ可能となればOK、です 例えばWorksheet「アクティブ」のCells(固定行位置,固定列位置)と Worksheet「他のシート」のCells(変数行位置,変数列位置)、両変数はその時点でプログラム(マクロ)が獲得済み、間にハイパーリンク(出来たら往復)をはるコードはどういうものになるでしょうか? うまく説明できているか、自信はありませんが何とか教えて頂きたくお願い致します

専門家に質問してみよう