- ベストアンサー
VBAの構文がわかりません。
1つのエクセルの中に2つのシートがあります。 1つ目のシート(「個人明細」)は1人分の個人の項目(名前や生年月日など)を表示できる型を作ってあります。セルにはVLOOKUP関数を使用して、社員コードを参照させ、もう1つのシート(「データベース」)から各項目を引っ張ってくるようにしてあります。ただ、「個人明細」のシートの欄外に、現在表示してある人の項目が1列で表示される枠を作ってあります。これは、この1列をコピーし、「データベース」上の同じ人の列に貼り付けすることで「データベース」を更新する仕組みとなっているためです。 問題は、この「データベース」を更新する仕組みを手動で行っており、この作業を簡略化することで間違った人に貼り付けすることを防止したいと考えています。 「個人明細」と「データベース」の欄外は左から 社員番号、健康保険番号、名前、生年月日、所属…となっています。 CommandButtonを押すことで、「個人明細」の欄外の1列をコピーし、「データベース」上で同じ社員番号の人の1列に貼りつける、 という構文を教えていただきたいと思っております。 底辺わかりづらいかと思いますが、よろしくお願い致します。 例 「個人明細」 983404 2343 山田五郎 S37.4.5 営業本部 「データベース」 ・ ・ 983322 2101 鈴木一郎 s44.2.3 本社総務 983404 2343 山田五郎 s37.4.5 _____ ・ ・ ボタンを押すと「個人明細」の1列をコピーし 「データベース」上で「983404」を探し 合致した列に貼りつける
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
「データベース」の社員番号の列を頭から比較していって、「個人明細」の社員番号と 一致した行に放り込むのはどうでしょう。
その他の回答 (3)
- n-jun
- ベストアンサー率33% (959/2873)
ANo.1です。 >頭から比較するやり方は、どういう構文になるでしょうか。 >簡略で構いませんので、教えてください。 については、ANo.2さんが参考コードを提示されてます。 そこで不明であれば、まずは調べることです。 参考書でも最初の方に書かれているかと思います。 が、”詳しくない”と言っても”覚えるしかない”としか言えないくらい基本的なことですし。
お礼
ありがとうございます。 なんとか見様見真似で解決することができました。 ちゃんと一から勉強しようと思います。 ありがとうございました。
- kangou
- ベストアンサー率33% (1/3)
はじめまして 何とかなりそうなものを作りましたので 参考にして 組み込んでください。 なお 次の2行はデバッグのためのものです 削除してよいです。 条件の次のコード中で ("F1")を含む1行 、 ("G1")を含む1行 条件1 一つ目のシートは個人明細になる シート名 個人明細 条件2 一つ目のシートは一人分の個人項目がある。 条件3 二つ目のシートはデータベースになる シート名 データベース 条件4 二つ目のシートの項目順は次の列に登録されている。 A列 社員番号 B列 健康保険番号 C列 名前 D列 生年月日 E列 所属 条件5 一つ目のシートのセルには VLOOKUP関数にて 二つ目のシートのデータベースより抽出されて表示される。 条件6 「個人明細」の欄外の1列をコピーし、 「データベース」上で同じ社員番号の人の1列に貼りつける。 条件7 個人明細の欄外も 項目順は 条件4と同じ並びです。 条件8 A1 は 社員コード 検索キーです。 条件9 A1:E65536はシートのデータベース範囲です。 条件10 F1は実際のデータが何行目かを表示しています。 条件11 G1は社員コードが無い場合のエラー処理 Private Sub CommandButton1_Click() Dim myR On Error GoTo ErrorHandler With Worksheets("データベース") myR = Application.WorksheetFunction.Match _ (.Range("A1"), .Range("A1:E65536"), 0) .Range("F1").Value = myR ' 何行目表示 Worksheets("データベース").Range _ ("B" & myR).Value = .Range("B" & myR).Value ' Bは列番号です。 この場合は 健康保険番号 End With Exit Sub ErrorHandler: Worksheets("データベース").Range("G1").Value = "該当無し" End Sub
お礼
自己解決で申し訳ありません。 どうにかこうにか解決することができました。 丁寧にご回答いただき、ありがとうございました。
補足
返答が遅くなり申し訳ありません。 試してみたのですが、行数までは表示できました。 それをその行数に貼りつける構文を教えてください。 「それくらい調べろ!」 と言われてしまいそうですが、よろしくお願い致します。
- fujillin
- ベストアンサー率61% (1594/2576)
面倒な時は、ワークシート関数を利用するという手もあります。 Application.WorksheetFunction.Match(社員番号, データベース範囲, 0) で、通常の関数のように取得できるはずですが、私の環境では、なぜかMatch関数が取得できません(ヘルプでは使用可となっているのですが・・・) 後は、No1様の回答のように、頭から比較していくのが一番簡単でしょう。 もし、データベースが番号順にソートしてあれば、中間点で比較してゆく方法などで検索時間の短縮を計れますが、ロジックが複雑になる分コードが長くなる可能性があります。 間単にイメージだけ書くとこんな感じでしょうか Dim elm As Range, flag As Boolean flag = False For Each elm In Sheets("データベース").Range("番号範囲") If 社員番号 = elm.Value Then flag = True: Exit For Next elm If flag Then Sheets("データベース").Range("範囲(1行目)") _ .Offset(elm.Row - 1, 0).Value = Sheets("個人明細").Range("範囲").Value Else '//番号がない場合の処置 End If
お礼
漸く試行錯誤を繰り返した結果、 なんとか形になり、微調整を加えながら順調に機能しております。 迅速にご回答いただき、ありがとうございました。
補足
回答ありがとうございます。 遅くなり申し訳ありません。 今いろいろと試しているのですが。 イメージで書いていただいた内容について。 For Each~とOffset~の文はどういうことでしょうか。 あまり詳しくないので教えてください。
補足
回答ありがとうございます。 遅くなりましてすみません。 初心者なもので;; 頭から比較するやり方は、どういう構文になるでしょうか。 簡略で構いませんので、教えてください。