• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:難しい挿入マクロを教えて下さい)

挿入マクロの難問について

このQ&Aのポイント
  • 難しい挿入マクロを教えて下さい。あるフォルダに、『商品コード.xls 』というブックと、『データ【1】.xls 』という名前のブックが【1】~【76】まであります。『商品コード.xls 』のコードを基準にして、『データ【1】.xls 』 ~ 『データ【76】.xls 』 の全てのデータのD列を検索し、E列を挿入して、商品を記入したいのです。挿入する際には、半角大文字に揃えてから検索を行いたいのですが、それは可能でしょうか?
  • また、『データ【1】.xls 』 ~ 『データ【76】.xls 』 にE列を挿入し、商品名がついていないコードを新たに作り、『商品コード.xls 』に追加して更新した後、再び全てのブックを検索したいと考えています。これはマクロの一部を変更することで対応できるでしょうか?
  • 質問がわがままで勝手なものであることをお詫び申し上げますが、この挿入マクロについてご指導いただけないでしょうか?お手数をおかけしますが、よろしくお願いいたします!

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

  • ベストアンサー
  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.4

e)但し、『商品コード.xls 』だけは、「商品コード」のある列が他の『データ【*】.xls 』と異なりますので、この ブック だけは、同様の コード により、別途、単独に行なっておきます。 ==================== 【3】「D列を検索し、E列を挿入して、商品を記入」する操作 f)先ず、「E列を挿入」します。  この程度の操作は、[新しいマクロの記録] で コード を採取する習慣を付けましょう。 Columns("E:E").Insert Shift:=xlToRight g)次に「D列を検索し、商品を記入」する操作ですが、最も簡単なのは、 ・『商品コード.xls 』も開いておいて、 ・E列に、「=VLOOKUP(D2,[商品コード.xls]Sheet1!$B:$C,2,FALSE)」という式を入れる。 ということになろうかと存じます。 '--------------- Sub 第3段階()   Columns("E:E").Insert xlToRight   With Range(Range("E2"), Cells(Range("D" & Rows.Count).End(xlUp).Row, "E"))     .FormulaR1C1 = "=VLOOKUP(RC[-1],[商品コード.xls]Sheet1!C2:C3,2,FALSE)"     .Copy     Range("E2").Select     Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _       :=False, Transpose:=False     Application.CutCopyMode = False     .Replace "#N/A", ""   End With End Sub '---------------  「第3段階」を実行すると、「E列を挿入」し E列 に上記の計算式を施してから、すべて値に変化し、その中で「#N/A」を表示している セル を、すべてクリアします。 ==================== 【4】『商品コード.xls 』を更新する作業 h)案外、これが難しい作業になるかも知れません。  とりあえず、「第3段階」を終えた時点で、E列 が空白の行の D列 の「商品コード」を『商品コード.xls 』の B列 の後ろに コピー する、という作業になろうかと存じますが、「E列 が空白の行」は、E列 を選択しておいて、[ジャンプ] メニュー - [空白セル] を選択する操作を [新しいマクロの記録] で記録します。  これまでにも何度か出てきましたが、[End プロパティ]・[Offset プロパティ]、また、[Resize プロパティ] などについては、ザクッとお勉強しておいてください。 http://www.google.co.jp/webhp?q=#sclient&q=Offset+Resize+End+%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB '--------------- Sub 第4段階()   With columns("E:E") 'Range(Range("E2"), Cells(Range("D" & Rows.Count).End(xlUp).Row, "E"))     .SpecialCells(xlCellTypeBlanks).Offset(, -1).Copy     Windows("商品コード.xls").Activate     Range("B" & Rows.Count).End(xlUp).Offset(1).Select     ActiveSheet.Paste     Application.CutCopyMode = False   End With End Sub '--------------- ==================== 【5】さて、冒頭の見出しに「??」と書きましたが、実は、この段階で「手作業」が必要になります。  と申しますのは、ここで、【6】 の操作に移りたいトコロですが、肝心なコトが抜けています。  【4】の段階では、 >基準となる『商品コード.xls 』に追加(更新) されただけであって、その「商品コード」に対応する「商品」名が記入されていないのではありませんか?  したがって、ここで、『商品コード.xls 』の C列 に、手作業で「商品」名を記入していきます。  その前に、各ブック から寄せ集められた「未登録の商品名」がダブっていることも考えられますので、先ず、『商品コード.xls 』の D列 を並べ替えましょうか。  ≪実は、『商品コード.xls 』の D列 には、[VLOOKUP 関数] で、別表から「商品名」を引っ張ってくるようにしてある≫ ということになれば、この段階も マクロ化 できます。 ==================== 【6】更新された『商品コード.xls 』で再度検索し直す操作 【7】最後のご質問  では、いよいよ「再検索」ですが、これは、「第3段階」の「E列を挿入」する操作を外せばよいだけかと存じます。  換言すれば、【2】~【4】までの操作は、1回行なえば、今後は必要のない操作かと存じます。  ですから、【2】~【4】までの操作を、1回行なっておけば、今後は、【3】から「E列を挿入」する操作を外した操作、及び【4】と【5】を1つにまとめておけば、そのまま使えるかと存じます。 ====================  以上、長々とご説明いたしましたが、一つずつ、よくご自身でお考えいただいて健闘されますことをお祈り申します。

p1_1q
質問者

お礼

DOUGLAS_さま、ご忠告も含め、このように丁寧なご説明を書いてくださって ありがとうございます。 わがままな注文に、親切に対応してくださり、感激しております。 【5】のご指摘も、ありがとうございます。おっしゃる通りです。 【3】の検索ですが、Find や xlWhole を使うとばかり思っていましたが、 VLOOKUP関数をマクロで表示させるという方法が、想像もしなかったことで 大変参考になりました。 難しいコードを難しく考えすぎず、今の自分にできる範囲でのコードを考えてみることを学びました。 教えていただいたコードと解説、保存して勉強します。 ありがとうございました。

その他の回答 (3)

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.3

#かなりの長文になってしまいましたので、回答を2つに分けさせていただきます。 #一つずつよくご理解いただきながら、じっくりとお読みください。  全部のコトをいっぺんに済まそうというのは、p1_1q さんの スキル で対応できますでしょうか?  せめて、今、ここまで出来ているという VBA の コード を提示されてから、どこをどう直したらよいかみたいなご質問の方がよさそうに感じます。  それと、最近では、WEBページ にそれなりの教材がたくさんありますので、WEB検索 も一つの技術かと存じます。 >いろいろ調べてみましたが、とても難しく、限界です。 とのことで、確かに難しい操作かとは存じますが、全部いっぺんに済ますのではなくて、操作の内容をよく整理し、ご自身でよく理解して、一つずつやっつけていくという心構えが大切かと存じます。 >ご指導をお願いしたくて、質問させていただきます。 とお書きですので、ズバリの コード ではなくて、敢えてバラバラの コード を書きましたので、後は、組み合わせ方を、ご自身で工夫なさってください。 ====================  さて、お説教はこのぐらいにして、p1_1q さんのご要望を、操作の順にまとめると、下記のようなことになろうかと存じます。 【1】あるフォルダに、『商品コード.xls 』(B列とC列だけのデータ)というブックと、『データ【1】.xls 』 という名前のブックが【1】~【76】まで(様式は全部おなじ)全部で 77個のブックがあります。 【2】『商品コード.xls 』のB列(商品コード)と、『データ【1】.xls 』 ~ 『データ【76】.xls 』 のD列の英字が、全半角・大小文字が混在していますので、これを、半角大文字に揃えてから検索   【3】『商品コード.xls 』のコードを基準にして、『データ【1】.xls 』 ~ 『データ【76】.xls 』 の全てのデータのD列を検索し、E列を挿入して、商品を記入したいのです。 【4】『データ【1】.xls 』 ~ 『データ【76】.xls 』 にE列を挿入・検索後、ひとつひとつのブックをみていき、E列に商品名がついてないコード(『商品コード.xls 』にないもの)を 新たに作り、基準となる『商品コード.xls 』に追加し(更新) 【5】?? 【6】更新された『商品コード.xls 』で再度 76個全てを検索し直します。   【7】一度 E列を挿入・商品を記入した後、更新した『商品コード.xls 』で再び検索するというマクロは、コードのどこかの箇所を変更すれば、対応できるでしょうか? それとも、もう一度 作りなおすことになるのでしょうか? ====================  それでは、ここで、上記の1つずつについて詳しくご説明いたします。 【1】「あるフォルダ」内の「全部・・・のブック」に対する処理 a)先ず、すべての ブック を拾い出す コード を書きます。  [Dir 関数] 関数を用い、[Do...Loop ステートメント] で処理します。 b)すべての ブック に対して、同じ操作を施す コード を (a) に挿入します。  下記の例では、「Debug.Print MyName」の部分です。 '--------------- Sub 第1段階()   Dim MyPath As String   Dim MyName As String   MyPath = "D:\hoge\"   MyName = Dir(MyPath & "データ【*】.xls")   Do While MyName <> ""     Debug.Print MyName     MyName = Dir   Loop End Sub '---------------  [Dir 関数] の ヘルプ をご覧くださいね。  「MyPath」は実際の「あるフォルダ」の フルパス に書き換えてください。  「第1段階」を実行すると「あるフォルダ」の中にある「データ【??】.xls」という名前の ファイル の名前が、VBE(Visual Basic Editor)の イミディエイト ウィンドウ に吐き出されます。  今後は、「同じ操作を施す コード」、つまり「Debug.Print MyName」の部分を必要に応じて書き換えていきます。 http://www.google.co.jp/webhp?q=#sclient&q=%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E5%86%85%E3%81%AE%E5%85%A8%E3%81%A6%E3%81%AE%E3%83%96%E3%83%83%E3%82%AF ==================== 【2】英字を半角大文字に揃える操作 c)「様式は全部おなじ」ブック の「データシート」の「D2 セル から D列最終行まで」という範囲設定でよろしいでしょうか?  この場合、 ・【1】の操作により ブック を1つずつ開く。 ・「データシート」の「D2 セル から D列最終行まで」を選択する。 ・「範囲内のすべての セル」の「英字を半角大文字に揃える」 ・ブック を保存終了する という段取りになろうかと存じます。  「D2 セル から D列最終行まで」というのは、 Range(Range("D2"), Range("D2").End(xlDown)) のような感じで取得できます。  D列が「D2」の 単一セル しかない場合、あるいは D列 に 空のセル があるかも知れませんので、 Range(Range("D2"), Range("D" & Rows.Count).End(xlUp)) の方がよいかも知れません。  前者は、D2 セル から [Shift] + [Ctrl] + [↓] で選択する範囲、後者は D列の下端 から [Ctrl] + [↑] で選択した セル と D2 セル の間にある セル範囲 です。 d)次に、#1 さんのご回答にもありますように、「英字を半角大文字に揃える」操作には、[StrConv 関数] を用います。  「半角」にし、さらに「大文字」にする訳ですから [StrConv 関数] を繰り返して用いることになります。  ただ、範囲内のすべての セル に対して同じ操作を行なう訳ですから、これをどうしたらよいか? ですが、ユーザー定義関数 を作っても、結局、[For(Each)...Next ステートメント] で 1セル ずつ 回すコトになります。 '--------------- Sub 第2段階1()   Dim i As Long   Sheets("データシート").Select   For i = 2 To Range("D" & Rows.Count).End(xlUp).Row     Cells(i, "D").Value = StrConv(StrConv(Cells(i, "D").Value, vbNarrow), vbUpperCase)   Next i End Sub '---------------  「第2段階1」を実行すると、「D2 セル から D列最終行まで」1セル ずつ「英字を半角大文字に揃える」操作が行なわれます。  ただ、「多いものは 5万行ほどもあります」とのことですので、場合によっては、 ・「必ず空いている列」に「=UPPER(ASC(D2))」という式を立てる ・その値を D列 に コピー する ・最後に、補助列を削除する とした方が速いのかも知れません。  [新しいマクロの記録] によって、上記の操作を手作業で行なうと、下記のような コード を得ることができます。 '--------------- Sub 第2段階2()   With Range(Range("D2"), Range("D" & Rows.Count).End(xlUp))     .Offset(, 5).FormulaR1C1 = "=UPPER(ASC(RC[-5]))"     .Offset(, 5).Copy     Range("D2").Select     Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _       :=False, Transpose:=False     Application.CutCopyMode = False     .Offset(, 5).EntireColumn.Delete Shift:=xlToLeft   End With End Sub '---------------  「第2段階2」を実行すると、D列 より「5列右側」の「I列」を補助列として作業が行なわれます。  これについては、マニアック な手法もあるようですが、初心者向けの基本的な操作のみお知らせいたします。 http://www.google.co.jp/webhp?q=#sclient&q=%E7%AF%84%E5%9B%B2%E5%86%85%E3%81%AE%E8%8B%B1%E5%AD%97%E3%82%92%E5%8D%8A%E8%A7%92%E5%A4%A7%E6%96%87%E5%AD%97+%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB

  • WWolf
  • ベストアンサー率26% (51/192)
回答No.2

こんにちは。 まず、したいことのイメージを整理(シュミレーション)してみてください。 全て書くのはよくないかも知れませんので、すべては書きません。 (イメージ1)商品コードを見つけるとE列を増やすというロジックを組み込むことによりロジックそのものが複雑になる。 (する事1)よって、データシートのブック1-76については事前にE列を増やす事のみを手作業またはマクロで実行。 (イメージ2)商品コードブックに、全半角・大小文字が混在してることを、半角大文字に揃えてから検索するのもなー。 (する事2-1)運用的に必須条件として商品コードに全半角・大小文字が混在しないといけないのか?違えば、商品コードブックに対し全半角・大小文字を半角大文字に一括変換しておく。 (する事2-2)折角、半角大文字に統一したんだからいっその事、今後は商品コードの入力には規制しておく。 などなど・・・ それらをしておいてから、本当にすべきこと(最も面倒なこと)を整理し直しロジックを考えてみてください。

p1_1q
質問者

お礼

WWolfさま、そんなふうに順番に書き出してみたら、 するべき事が、とてもよくわかりますね。   頭が固く、ひとつのコードに納めなければならない と思っていました。 手作業で出来るところ、関数でできるところは先にやっておいて その後、マクロを分けて実行する方法がある事、非常に勉強になりました。   ありがとうございました。

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.1

『VBA 全角 半角』程度のキーワードで WEB検索すれば StrConv という関数がすぐに見つかるし、大文字小文字も 同じ。 セルの参照式では難しいけど、マクロで多少長くなっても 手順を順に書いていくだけならプログラムとしては並。 平凡な内容なので、ちゃんと勉強してればできる内容です。

p1_1q
質問者

お礼

並・・・そうですね、ごもっともです。 私にとっては、とても難しいのですが、 引き続き、ちゃんと勉強をして考えてみます。 ありがとうございました。

関連するQ&A