Excel VBA質問箱 IV

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

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


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

【76351】検索して置換 T氏 14/11/2(日) 23:40 質問[未読]
【76352】Re:検索して置換 γ 14/11/3(月) 7:08 発言[未読]
【76353】Re:検索して置換 γ 14/11/3(月) 22:34 回答[未読]
【76354】Re:検索して置換 T氏 14/11/4(火) 9:29 お礼[未読]
【76355】Re:検索して置換 γ 14/11/4(火) 22:06 発言[未読]

【76351】検索して置換
質問  T氏  - 14/11/2(日) 23:40 -

引用なし
パスワード
   下のようなデータがあったとします。
A列B列C列
1 2 3
2 3 2
3
A列=元データ
B列=違う値
C列=正しい値
A列にあるデータに対し
違う値と正しい値が入力されています。
(2ではなく3、3ではなく2)
これをVBAを使うことで
D列なる正しいデータを出力させたいです。
<実行結果>
A列B列C列D列
1 2 3 1
2 3 2 3
3    2
お知恵をかしてください。

【76352】Re:検索して置換
発言  γ  - 14/11/3(月) 7:08 -

引用なし
パスワード
   単純に置換してしまうと、前の置換結果が次の置換に影響してしまう、
ということですね。

A列の各セルごとに、
  それがB列にあるか判定し、
  あれば、対応するC列の値を  D列に書き込み
  なければ、A列の値をそのまま D列に書き込む
繰り返し

という処理をすればいいと思います。

B列にあるかどうかの判定は、
B列の数が説明のように少なければ、If文でそのまま書いてもよいし、
Select Case ステートメントを使っても良いでしょう。

数が多ければ、
Application.Matchを使い、
マッチしなければ、返ってくる値が IsErrorで真になることを使います。

(別法として、Dictionaryを使うことも可能でしょう。
 B列の値と対応するC列の値をこれに保持しておいて、
 dic.Exisits(A列の値)で値の有無を問い合わせることができ、
 対応する値を取得することも簡単にできます。)

これらをヒントに少しトライしてみて下さい。

【76353】Re:検索して置換
回答  γ  - 14/11/3(月) 22:34 -

引用なし
パスワード
   コメントを待っていましたが、
平日は時間がとれないので、準備しておいたものを示しておきます。
参考にしてください。

Sub test1() '例示されたケースだけに有効
  Dim r As Range
  Dim v As Variant

  For Each r In Range("A1", Range("A1").End(xlDown))
    v = r.Value
    Select Case v
    Case Cells(1, "B").Value
      v = Cells(1, "C").Value
    Case Cells(2, "B").Value
      v = Cells(2, "C").Value
    End Select
    r.Offset(0, 3).Value = v
  Next
End Sub

Sub test2() ' 一般的なケースに適用可能
  Dim r As Range
  Dim m As Variant

  For Each r In Range("A1", Range("A1").End(xlDown))
    m = Application.Match(r, Columns("B"))
    If Not IsError(m) Then
      r.Offset(0, 3).Value = Cells(m, "C").Value
    Else
      r.Offset(0, 3).Value = r.Value
    End If
  Next
End Sub

Sub test3() ' 一般的なケースに適用可能
  Dim dic As Object
  Dim r As Range

  Set dic = CreateObject("Scripting.Dictionary")

  For Each r In Range("B1", Range("B1").End(xlDown))
    dic(r.Value) = r.Offset(0, 1).Value
  Next

  For Each r In Range("A1", Range("A1").End(xlDown))
    If dic.exists(r.Value) Then
      r.Offset(0, 3).Value = dic(r.Value)
    Else
      r.Offset(0, 3).Value = r.Value
    End If
  Next
End Sub

【76354】Re:検索して置換
お礼  T氏  - 14/11/4(火) 9:29 -

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

Findメソッド等使って考えていましたが
まったくうまくいかず困っていました。。。

TEST3を使っていきたいと思います!
もちろん、自分で意味をちゃんと理解したうえで使います。

ありがとうございます!

▼γ さん:
>コメントを待っていましたが、
>平日は時間がとれないので、準備しておいたものを示しておきます。
>参考にしてください。
>
>Sub test1() '例示されたケースだけに有効
>  Dim r As Range
>  Dim v As Variant
>
>  For Each r In Range("A1", Range("A1").End(xlDown))
>    v = r.Value
>    Select Case v
>    Case Cells(1, "B").Value
>      v = Cells(1, "C").Value
>    Case Cells(2, "B").Value
>      v = Cells(2, "C").Value
>    End Select
>    r.Offset(0, 3).Value = v
>  Next
>End Sub
>
>Sub test2() ' 一般的なケースに適用可能
>  Dim r As Range
>  Dim m As Variant
>
>  For Each r In Range("A1", Range("A1").End(xlDown))
>    m = Application.Match(r, Columns("B"))
>    If Not IsError(m) Then
>      r.Offset(0, 3).Value = Cells(m, "C").Value
>    Else
>      r.Offset(0, 3).Value = r.Value
>    End If
>  Next
>End Sub
>
>Sub test3() ' 一般的なケースに適用可能
>  Dim dic As Object
>  Dim r As Range
>
>  Set dic = CreateObject("Scripting.Dictionary")
>
>  For Each r In Range("B1", Range("B1").End(xlDown))
>    dic(r.Value) = r.Offset(0, 1).Value
>  Next
>
>  For Each r In Range("A1", Range("A1").End(xlDown))
>    If dic.exists(r.Value) Then
>      r.Offset(0, 3).Value = dic(r.Value)
>    Else
>      r.Offset(0, 3).Value = r.Value
>    End If
>  Next
>End Sub

【76355】Re:検索して置換
発言  γ  - 14/11/4(火) 22:06 -

引用なし
パスワード
   尤も、普通は
D1: =IFERROR(VLOOKUP(A1,$B$1:$C$3,2,FALSE),A1)
などとするほうが早いでしょうけど。
2003以前なら、IFとVLOOKUPを組み合わせます。

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