• ベストアンサー

VBAによる数値変換がうまくいきません

仕事で必要なIDの変換ツールを、EXCELを使って作っています。 いつもは手動で変換しているのですが、頻繁に作業を行わなければならないのと、作業が煩雑で入力ミスも多いため、それを防ぐためにプログラムで自動化してしまおうと考えています。 変換前  変換後  1000   1001  1001   1001  1002   1002  1003   1002  1004 → 1001  1005   1001  1006   2002  1007   1003  1008   1001  1009   1004  1010   1099 このような4~5桁の数字を、変換表にしたがってマクロで自動変換するように、ネットで見つけたVBAのプログラム文に手を加え作っているのですが、一部の数字がうまく変換できません。 ・数字の変換に関して、特に法則のようなものはありません。すべて変換表にしたがって変換しています。 ・変換しなければならないIDの数は、100個以上あります。 現在のVBAのプログラムは、以下の通りです。 Sub 変換() Dim ws As Worksheet Dim idx As Long Application.ScreenUpdating = False ActiveSheet.Copy after:=ActiveSheet ActiveSheet.Name = "変換後" Set ws = ActiveSheet With Sheets("変換表") For idx = 1 To .Cells(65536, 1).End(xlUp).Row If .Cells(idx, 1) <> "" Then ws.Cells.Replace What:=.Cells(idx, 1).Value, Replacement:=.Cells(idx, 2).Value, _ LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False End If Next idx End With Application.ScreenUpdating = True End Sub VBAやマクロに関する知識がほとんど無いので、何が原因なのか、どこに原因があるのかが分かりません。 どなたか詳しい方、お力を貸してください。 よろしくお願いします。

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

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

"変換後"のシートの値を置き換えたいのですよね? だとすると、こういうことでしょうか?  ・"変換表"のA列に変換前のコード、B列に変換後のコードがあると仮定  ・表に値がみつからない場合、背景色を赤(カラーコード3)にしています Sub test() Dim ws As Worksheet, rng As Range, fnd As Range Dim idx As Long Application.ScreenUpdating = False ActiveSheet.Copy after:=ActiveSheet ActiveSheet.Name = "変換後" Set ws = ActiveSheet '// 変換表の範囲を取得 With Sheets("変換表")  Set rng = .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp)) End With With ws For idx = 1 To .Cells(65536, 1).End(xlUp).Row  If .Cells(idx, 1) <> "" Then  '//変換表と値を比較  Set fnd = rng.Find(what:=.Cells(idx, 1).Value, LookAt:=xlWhole)   If fnd Is Nothing Then   .Cells(idx, 1).Interior.ColorIndex = 3  '//値が無い場合背景を赤(=3)に  Else   .Cells(idx, 1).Value = fnd.Offset(, 1).Value '//値があれば置き換え  End If End If Next idx End With 'Application.ScreenUpdating = True End Sub

jazz-mas01
質問者

お礼

ありがとうございます。 素晴らしいです。完璧に動作しました! 助かりました。ありがとうございます。

jazz-mas01
質問者

補足

すみません、さらに合わせて質問なのですが、 この上のコードにさらに追加して、 変換前         変換後 1000,1003,1010   → 1001,1002,1099 1000,,,1003,,1010 → 1001,,,1002,,1099 というように、一つのセルに「,」区切りの複数のIDが入っている場合でも 「,」はそのままで変換できるようにしたいのですが、可能でしょうか。 よろしくお願いします。

その他の回答 (5)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.6

No2です。補足で… No.5で「あまりお勧めしない」と書きましたが、  『比較表に無いものがあっても気にせず、あるものだけ変換できれていればよい』 という感じの機能であるなら、もともとのロジックのほうが簡単ですし、そのあたりは#1様が回答なさっていると思います。 ただし、変換前のコードと、変換後のコードがいろいろ重複しているようなので、ループの中で、一度コード変換したものが、つぎのループで再変換されることが無いように、表の方の順序を調整しておく必要があるような気がします。 もともとの、不具合はこのあたりに起因するものではないでしょうか?

jazz-mas01
質問者

補足

No.5、6と併せてご返答させていただきます。 本当に皆さんから色々なアドバイスをいただいているのに、自分がプログラムもVBA、マクロも全く分からないので、いただいたアドバイスを全く役に立てずにいる状態です。 ひとまずは時間が無かったので、変換しきれなかったIDに関しては、表にまとめて手動で変換することにしました。ツールとしては不完全なものになってしまいましたが、作業効率を上げる事は出来そうです。 >『比較表に無いものがあっても気にせず、あるものだけ変換できれていればよい』 ツールの方向性としては、その方向で考えています。ツールを使って自動抽出したID番号を、機械的に変換するだけのツールなので、変換表以外のコードが出てくることはまずありません。 変換さえエラーが出なければ、機能的には問題はありません。 ツールの改良に関しては、皆さんのご意見を参考にして、仕事の合間を見て行おうと思います。少し自分でもVBAやマクロを勉強して、皆さんからのアドバイスを理解できるようにならないといけないですね。 ご回答いただいた皆様、どうもありがとうございました。

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.5

No2です。 >「,」はそのままで変換できるようにしたいのですが、可能でしょうか。 可能です。 いずれにしろ、それぞれのコードを分解しないと表と比較できないので  dat = Split(.Cells(idx, 1).Value, ",") みたいにして分解しておいて、 これまでと同様に、個別コードを表と比較して変換してから、  Join(dat, ",") などのように、再度、連結してから、その値を戻すことになります。 (当然ながら、","が無い場合でも処理できるようにしておく必要があります) また、表中に該当するコードがなかった場合の処置をどうするのかなどを、きちんと決めておく必要もあります。 まぁ、複雑になりそうなので、あまりお勧めはしませんが…

  • turuzou
  • ベストアンサー率33% (15/45)
回答No.4

勘違いならご免なさい。 対象の数字の全角と半角の違いとか? StrConv 関数等を使用してみるとか? 失礼しました。

jazz-mas01
質問者

補足

文字はすべて半角です。 StrConv 関数は、設定した文字列を形式変換するためのものなのですね。 今は、特に使用していません。 よろしくお願いします。

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

#1です。 >残念ながら、アドバイスをいただいたやり方では、うまくいきませんでした。 >何か、ほかのところに原因があるのでしょうか。 #2さんが、完璧だというなら、今さら、何か新たにアドバイスを書くつもりもありませんが、私が頭が悪いのでしょうか、どういう問題があるのか、今もさっぱり分かりません。 その元のコード自体に不足している部分があるはずだとしか思えませんね。 私は、わざわざ、別のコードを書き直すほどではないはずだと思っています。特別に、問題があるコードではありません。ただ、おそらく、質問者さんが書いていない情報に、大事な問題が残っているはずだとしかいえません。 元のコードは、文字列を変換するもので、質問中には、数字を変えるように書いていたのだから、xlWhleと書いたのだけれども、どういう状況で上手く行かないのか、書かれていないのでは、私の知識では、今の状況下に解決は見えません。 単なる置換のコードなんでしょうから、難しいものではないはずです。 Replace メソッド自体は間違いないはずです。もしかしたら、もともと、だいたいはできていて、#2の補足の問題ではなかったのではないでしょうか。そうしたら、分かるわけありません。 ただし、 >変換前         変換後 >1000,1003,1010   → 1001,1002,1099 >1000,,,1003,,1010 → 1001,,,1002,,1099 ワークシートに、「.(カンマ)」切り自体で置いておくこと自体、標準的なものではないようですね。

jazz-mas01
質問者

補足

申し訳ありません。私の質問の仕方、返答の仕方に問題があったようです。 変換したい数列なのですが、 "2006" ",,,1009,,,2005,2006,,," という感じで、「"」と「,」で区切られた数列です。これを変換表にしたがって、「"」と「,」は残したまま、数字だけを変換したいのです。 それで、一番最初の質問に記載したコードでは、とりあえず変換はできるのですが、一部の数字の変換がうまくいきません。数字は4桁から5桁で、変換できていない数字は、主に5桁の数字や、変換の過程で桁数が変わるものが多いように思います。 たとえば 変換前   変換表   変換後  10001  11003   10011  11004  9002    9001  6001   11002   9002  1006   2002    2001 という感じです。ただ、同じような数字が正常に変換されているので、これが原因ではないような気がしています。 また、変換表は「変換前のID」と「変換後のID」の2列しかない単純なものなのですが、これを変換前のIDを優先して並び替えたときと、変換後のIDを優先して並び替えたときで、変換結果が異なってくるのですが、その理由も良くわかりません。 表の書式なども関係があるのでしょうか。今現在は、変換するデータを貼り付けるセルを「文字列」に、変換表を「標準」に設定してあります。 VBA、マクロに関しては全く知識が無いので、説明もうまくいかずご迷惑をおかけしますが、どうかよろしくお願いいたします。

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

こんばんは。 質問の内容のコードは、文字列を対照にしたもののようです。 一部分があったら、その部分だけを替えるという主旨ですが、入れ替えという方式です。 一度、以下の部分を変えてみてください。 前:LookAt:=xlPart   ↓   LookAt:=xlWhole これで、どうなるか様子をみてください。

jazz-mas01
質問者

お礼

ありがとうございます。 残念ながら、アドバイスをいただいたやり方では、うまくいきませんでした。 何か、ほかのところに原因があるのでしょうか。

関連するQ&A

  • エクセルのVBAの記述について

    VBAの記述についてなのですが、 Sub filter() Dim gyo As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim ws3 As Worksheet Set ws1 = Worksheets("データ") Set ws2 = Worksheets("チーム") Application.ScreenUpdating = False ws2.Range("A4:BH30").Clear gyo = ws1.Range("A65536").End(xlUp).Row ws1.Activate With ws1.Range(Cells(4, 1), Cells(gyo, 6)) .AutoFilter Field:=1, Criteria1:="A" .SpecialCells(xlCellTypeVisible).Copy ws2.Range("A4") Selection.AutoFilter End With Application.ScreenUpdating = True End Sub ならプログラムははしるのですが、 14行目を .SpecialCells(xlCellTypeVisible).Copy ws2.Range(Cells(4, 1)) だと 「実行時エラー 1004 Rangeメソッドは失敗しました Worksheet オブジェクト」 とでるのですが、出来ないのでしょうか? Cells(4, 1)の1のところを変数にして変えていきたいのですが、よい方法はありますか。 よろしくお願いいたします。

  • Excel VBA 数値を入れ 図形の線を変える

    図形を作成し、毎年更新をするのですが 数値を入れて、画像の線の幅を変更したいです。 下記、内容で作成したのですが、うまく動きません。 何が問題でしょうか? 数値を入れる場所は、B51になります。 Sub Macro1() ' Dim i As Integer Dim ws1 As Worksheet Set ws1 = ActiveSheet For i = 1 To 20 ActiveSheet.Shapes(ws1.Cells(50 + i, 1).Value).Select Selection.ShapeRange.Line.Weight = ws1.Cells(50 + i, 2).Value Next i End Sub

  • エクセル VBA

    VBA内で、そのVBAの実行を制御することは可能でしょうか? 下のようなコードを作ったのですが、 Sub 承認書作成() Dim ws0 As Worksheet, ws1 As Worksheet, r1 As Range Dim i As Long Dim nyuryoku(), chikuseki() Set ws0 = Worksheets("承認書作成") Set ws1 = Worksheets("顧客データ") Set ws2 = Worksheets("業者コード") Set ws3 = Worksheets("承認通知書") Worksheets("顧客データ").Select Range("テーブル1[[#Headers],[NO.]]").Select Selection.End(xlToRight).Select Selection.End(xlDown).Select Selection.ListObject.ListRows.Add AlwaysInsert:=False Range("B7").Select nyuryoku = Array("b5", "d5", "f5", "h5", "j5", "l5", "n5", "p5", "b6", "d6", "f6", "h6", "j6", "l6", "n6", "p6", "b4", "d4") '転記したいセルの位置 chikuseki = Array("0", "1", "5", "6", "8", "9", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "53", "54") '転記先の列のオフセット値  Set r1 = ws1.Range("f" & Rows.Count).End(xlUp).Offset(0) 'データ蓄積セル  For i = 0 To UBound(nyuryoku) r1.Offset(0, chikuseki(i)).Value = ws0.Range(nyuryokui)).Value '入力 Next MsgBox "入力完了" Dim lRowNum As Long '転記先となる行番号を求める lRowNum = ws1.Cells(Rows.Count, "b").End(xlUp).Row '転記 ws3.Cells(6, "d").Value = ws1.Cells(lRowNum, "j").Value ws3.Cells(17, "g").Value = ws1.Cells(lRowNum, "c").Value ws3.Cells(22, "g").Value = ws1.Cells(lRowNum, "l").Value ws3.Cells(22, "ac").Value = ws1.Cells(lRowNum, "ab").Value    Set ws0 = Nothing   Set ws1 = Nothing End Sub ここに、     If call Macro1 then call 承認書作成  '上のマクロです    Else: Msgbox"中止" 「Macro1を実行しないと承認書作成マクロを実行できない」 という コードを組み込みたいのですが、うまくいきません。 VBA内に同じVBAを組み込むことは不可能なのでしょうか?

  • Excel VBA 連番印刷

    昨日以下の質問をさせていただいた者です。 http://okwave.jp/qa/q8349562.html こちらで教えていただいた以下のコードに、 J2のセルに連番を振るコードを付け足したいと思い、 同じくこちらのサイトの過去の履歴にあった以下コードを参考にとやってみているのですが、 Next で指定された変数の参照が無効です。と言われてしまいます… 印刷部数の指定はいらず、sheet印刷のJ2セルに1から始まる連番を振りたいのです。 どのように修正をしたらいいのかご教示願います。 Sub Sample4() Dim i As Long, endRow1 As Long, endRow2 As Long, myArea1 As Range, myArea2 As Range Dim wS1 As Worksheet, wS2 As Worksheet, wS3 As Worksheet Set wS1 = Worksheets("DB") Set wS2 = Worksheets("印刷") Set wS3 = Worksheets("Sheet3") endRow1 = wS1.Cells(Rows.Count, "A").End(xlUp).Row Range(wS1.Cells(1, "A"), wS1.Cells(endRow1, "A")).AdvancedFilter Action:=xlFilterInPlace, unique:=True wS1.Range("A:A").Copy wS3.Range("A1") wS1.ShowAllData For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row If endRow2 > 9 Then Range(wS2.Cells(10, "B"), wS2.Cells(endRow2, "H")).ClearContents Range(wS2.Cells(10, "J"), wS2.Cells(endRow2, "J")).ClearContents End If wS1.Range("A1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "A") wS2.Range("B6") = wS3.Cells(i, "A") Set myArea1 = Range(wS1.Cells(2, "B"), wS1.Cells(endRow1, "H")).SpecialCells(xlCellTypeVisible) Set myArea2 = Range(wS1.Cells(2, "I"), wS1.Cells(endRow1, "I")).SpecialCells(xlCellTypeVisible) myArea1.Copy wS2.Activate ActiveSheet.Range("B10").Select Selection.PasteSpecial Paste:=xlPasteValues myArea2.Copy wS2.Activate ActiveSheet.Range("J10").Select Selection.PasteSpecial Paste:=xlPasteValues endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row 'Range(wS2.Cells(1, "A"), wS2.Cells(endRow2, "J")).PrintOut Next i wS1.AutoFilterMode = False wS3.Cells.Clear End Sub 連番印刷のコード Sub NumberPrint() Dim idx As Integer Dim res  res = Application.InputBox("印刷部数を入力してください", Type:=1)  If res > 0 Then   For idx = 1 To res    Range("AW3").Value = idx    ActiveSheet.PrintOut   Next idx  End If End Sub

  • Excel 改ページのマクロ

    同シート内で改ページを設定するマクロを、ここで教えてもらったのですが、改ページを判断するデータの列が関数(vlookup)で持ってきたデータの場合にうまく機能しません。下のマクロに手を加えれば可能でしょうか? Sub Macro4() Const col As String = "A" '改ページを判断するデータの列名 Dim idx As Long Dim sv sv = Cells(1, col).Value For idx = 1 To Cells(65536, col).End(xlUp).Row   If Cells(idx, col).Value <> sv Then     ActiveSheet.HPageBreaks.Add Before:=Rows(idx)     sv = Cells(idx, col).Value   End If Next idx End Sub

  • VBAの解説

    お世話になります 値、セルの操作ですが列数等の変更が生じたため変更を求められています。 下記VBA判りやすく説明できる方お願い致します。 Sub Macro1() Dim idxR, idxC, ptr As Integer Dim ws As Worksheet Set ws = ActiveSheet Worksheets.Add after:=ws ptr = 2 With ws .Rows(1).Copy Destination:=Range("A1") For idxR = 2 To .Range("A65536").End(xlUp).Row Cells(ptr, "A").Value = .Cells(idxR, "A").Value For idxC = 2 To 255 Step 2 If .Cells(idxR, idxC) = "" Then Exit For Else .Cells(idxR, idxC).Resize(1, 2).Copy Destination:=Cells(ptr, "B") ptr = ptr + 1 End If Next idxC Next idxR End With End Sub

  • 複数のCSVファイルを自動でエクセルに変換したい

    フォルダの中に、300近いCSVフォルダがあります。 ネットで探したマクロVBAでやってみたところ、一つのCSVファイルを選び、それをエクセルファイルに変換できました。 このマクロを使って、フォルダ内にあるすべてのCSVファイルを一気にエクセルに変換するには、どうしたらいいのでしょうか。 ご教授のほど、よろしくお願いいたします。 Sub CSVからXLSX() Dim varFileName As Variant varFileName = Application.GetOpenFilename(FileFilter:="CSVファイル(*.csv),*.csv", _ Title:="CSVファイルの選択") If varFileName = False Then Exit Sub End If Workbooks.Open Filename:=varFileName ActiveSheet.Cells.Copy ThisWorkbook.ActiveSheet.Cells ActiveWorkbook.Close SaveChanges:=False End Sub

  • エクセルVBAを修正したい

    数字を入力すると記号に変換になるマクロを 元ファイルを修正して作成したいのですが、 以下の記述が理解できません。 具体的にどのような処理をしているのか教えて下さい。 Do While Len(Range("C" & CStr(I)) & Range("D" & CStr(I))) > 0 For J = StartCol To EndCol If Len(ActiveSheet.Cells(12, J).Value & ActiveSheet.Cells(13, J).Value) > 0 Then tmp = "" If ActiveSheet.Cells(I, J).Value = "×" Or ActiveSheet.Cells(I, J).Value = "中止" Then ' ActiveSheet.Cells(I, J).Value = "中止" 'ActiveSheet.Cells(I, J + 1).Value = "" Else If Len(ActiveSheet.Cells(I, J).Value) = 0 Then K = -1 Else K = ActiveSheet.Cells(I, J).Value End If Select Case K Case 0 tmp = "×" Case 1 To 9 tmp = "△" Case Is >= 10 tmp = "○" Case Is < 0 tmp = "**" End Select

  • Excelの三つのVBAを一つにまとめる。

     初めまして、よろしくお願いします。当方全くの素人でVBAの基礎もよくわからず、ネットから拾ってきていじった三つのVBAがあります。この三つ、一つ一つは個別に機能するのですが、VBAとして正しいのかさえよく解っていません。この三つを一つにまとめて、同時に機能するようにしたいと頭を抱えています。 Sub TEST() Application.ScreenUpdating = False Application.EnableEvents = False ActiveSheet.Calculate Range("b10:b20").Insert shift:=xlShiftToRight Range("b10:b20").Value = Range("a10:a20").Value Application.OnTime TimeValue("09:00:00"), "TEST" Application.ScreenUpdating = True Application.EnableEvents = True ActiveWorkbook.Save End Sub ________________________________________________________________ Sub TEST1() Application.ScreenUpdating = False Application.EnableEvents = False ActiveSheet.Calculate Dim myCnt As Long Range("c30:c40").Copy Range("d30:d40").PasteSpecial Paste:=xlPasteValues Range("b30:b40").Copy Range("c30:c40").PasteSpecial Paste:=xlPasteValues Range("a30:a40").Copy Range("b30:b40").PasteSpecial Paste:=xlPasteValues nextTime = Now() + TimeValue("01:00:00") Application.OnTime nextTime, "TEST1" Application.ScreenUpdating = True Application.EnableEvents = True ActiveSheet.Calculate ActiveWorkbook.Save End Sub ________________________________________________________________ Sub TEST2() Application.ScreenUpdating = False Application.EnableEvents = False ActiveSheet.Calculate Dim myCnt As Long Range("c50:c60").Copy Range("d50:d60").PasteSpecial Paste:=xlPasteValues Range("b50:b60").Copy Range("c50:c60").PasteSpecial Paste:=xlPasteValues Range("a50:a60").Copy Range("b50:b60").PasteSpecial Paste:=xlPasteValues nextTime = Now() + TimeValue("00:10:00") Application.OnTime nextTime, "TEST2" Application.ScreenUpdating = True Application.EnableEvents = True ActiveSheet.Calculate ActiveWorkbook.Save End Sub ________________________________________________________________  解る方、よろしくお願いします。

  • エクセル2007 参照セルの値が認識されない

    エクセル2007の環境で下記マクロを実行すると、 アクティブシートのセルA1に数字が入っている場合、Sheet1のセルA1に値を転記しても そのセルA1の値をVLOOKUP関数で参照できません。 マクロに問題があるためなのか何処に問題があるのか分からないので教えてください。 宜しくお願いいたします。 【sheet】は アクティブシートの3行目から1000行目までのA列のセルをクリックしたらセルA1に値を表示 その後、下記【モジュール】を使用し、 アクティブシートのセルA1が空白の場合、 A列の数値をSheet1のセルA1に転記し、アクティブシートのA列の数値が空白になるまで循環する。 Sheet1のセルA1の値をVLOOKUP関数で参照した内容を表示、印刷します。 ----------------------------------------------------------------- '【sheet】 Private Sub Worksheet_SelectionChange(ByVal Target As Range) With Target If .Count > 1 + IsEmpty(.Value) Then Exit Sub If Application.Intersect(.Cells, Range("A3:A1000")) Is Nothing Then Exit Sub ActiveSheet.Cells(1, 1).Value = .Value End With End Sub ----------------------------------------------------------------- '【モジュール】 Sub TEST() Dim myBtn As Integer Dim myMsg As String, myTitle As String Dim WS1 As Worksheet, WS2 As Worksheet Dim i As Long myMsg = "●●●" myTitle = "確 認" myBtn = MsgBox(myMsg, vbYesNo + vbExclamation, myTitle) If myBtn = vbYes Then Set WS1 = ActiveSheet Set WS2 = Sheet1 If WS1.Cells(1, 1).Value = "" Then With WS1 For i = 3 To 65536 If .Cells(i, 1).Value = "" Then Exit For WS2.Cells(1, 1).Value = .Cells(i, 1).Value WS2.Cells(1, 2).Value = ActiveSheet.Name 'WS2.PrintOut Copies:=1 Next i End With ElseIf WS1.Cells(1, 1).Value >= 1 Then WS2.Cells(1, 1).Value = WS1.Cells(1, 1).Value WS2.Cells(1, 2).Value = WS1.Name 'WS2.PrintOut Copies:=1 Else End If End If End Sub -----------------------------------------------------------------

専門家に質問してみよう