• ベストアンサー

EXCEL で検索、更新したい

EXCEL でわからない箇所があり質問します。 前提条件 Sheet1 A列:名前 B列:年月 C列:値 データは、名前と年月で一意になるデータシートがあり マスターデータとして全データが登録されている Sheet2 A列:名前 B列:年月 C列:値 ある条件でとあるデータベースから抽出した名前と年月の一覧がある この段階で値のセルには何も入っていない やりたい事 (1)この状態でマクロを実行し、A列、B列を条件に該当する行から    C列を抽出しSheet2 にセット (2)Sheet2のC列の値を変更後、マクロの実行で    A列、B列の条件を元該当する行から、Sheet1の C列に値を更新 (3)もし、Sheet2のA列、B列の条件に該当しない行がある場合、    Sheet1に行追加しC列を格納 という事をしたいと考えています。 Sheet1 の全ての行をマクロでループさせて A列、B列をif分で比較し行を取得し、Sheet2 に張る場合、 遅くなるのであまりやりたくないと思っています Find 関数も考えたのですが、ヘルプを見る限り、条件が1つしか指定でき ないように思えるのですが、複数列の条件を指定できる Find 関数 あるいは、類似の関数とあかがあるのなら教えてください 最悪は、EXCEL ADO で、自分自身をSQLで抽出、Update、Insert を行う 事も考えていますが、 EXCELのセル内の式で、INDEX関数やDGET関数で簡単に抽出できるのに (ただ、値を変更するので式はかけないけど・・・) わざわざ、ADOでプログラムを組むのもどうなんだろうと疑問に思ってます。

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

  • ベストアンサー
  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.4

マスタデータのエクセルのシートSheet1の空き列に、 氏名(8桁程度の固定桁数)+年月(4桁または6桁固定) の(検索用)修正キーを作ります。 プログラムかまたはエクセル関数で作る。 両者文字列を&で結合する。 ー 短い氏名でも年月は左に詰めないこと (例)泉△一郎△△△200712のように 1月は01にする方式とする。 これで>名前と年月で一意になる、らしいのでキーの重複行は無いはず。 ーー これでSheet2の氏名+年月の条件データから、上記要領で修正キーをプログラムでつくり、Findメソッドの引数として使う。 (FindNextはありえないということだが、それでよいか。) ーー 見つかった行の必要な列(項目)のデータをSheet2の所定の列に セット。 並び順は影響しない。Sheet1のデータが追加されたとき、最下行に追加なら、前もって関数で、修正キーを作れるよう備えておくことができる。 ーー あとはMSクエリなどアクセス利用に持ち込むか。 もともとエクセルでやるのは無理がありそうです。

nak777r
質問者

お礼

回答ありがとうございます こちらも、条件となるセルの内容を足してキーを作成する方法ですね 私は思いつきもしなかったですが、、、ひょっとして定番なのでしょうか、グーグル先生には教えてもらえなかったのですが・・・ 早速明日にでも試してみたいと思います。 ありがとうございました

その他の回答 (4)

  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.5

VBAで処理するなら、例えば こんな感じで如何でしょうか。 > B列:年月 ということで、日にち が無いのでどういう形式になっているのか不明ですので ひょっとすると変更を要するかも知れません。 取敢えず、文字列の "200712" とか 数値の 200712 とか 日付形式の書式 yyyy/mm の場合で 動作するかと思います。 Sub GetValue() Dim Rng As Range Dim FRng As Range Dim Fst As String Dim Rw As Long Worksheets("Sheet2").Activate Rw = Cells(Cells.Rows.Count, 1).End(xlUp).Row Range("C2:C" & Rw).ClearContents With Worksheets("Sheet1")   For Each Rng In Range("A2:A" & Rw)     If Not IsEmpty(Rng) Then       Set FRng = .Range("A:A").Find(Rng.Value, lookat:=xlWhole)       If Not FRng Is Nothing Then         Fst = FRng.Address         Do           If Rng.Offset(, 1).Value = FRng.Offset(, 1).Value Then _             Rng.Offset(, 2).Value = FRng.Offset(, 2).Value           Set FRng = .Range("A:A").FindNext(FRng)         Loop Until FRng Is Nothing Or FRng.Address = Fst       End If     End If   Next End With Set FRng = Nothing End Sub 以上は(1)についてですが、(2)(3)については、ちょっと必要性が分りません。 (2)の「Sheet1の C列に値を更新」については、今 参照したばかりなので値は同じ筈。 (3)の「該当しない行がある場合、Sheet1に行追加しC列を格納」については、 該当しなければ、C列は空白な筈 それを格納とは? 解釈が違っていたらごめんなさい。

nak777r
質問者

お礼

回答ありがとうございます EXCELは、会社にあるので、明日にでもまた試してみたいと思います。 (2)(3)は、マクロで、Sheet1からSheet2に取り出したあと、 Sheet2の方の値を編集した後マクロで、編集した値をSheet1に 反映させたい、 また、Sheet2の名前と年月で、Sheet1に無い場合は追加したい というものでした。 が、何とかなりそうです ありがとうございました。

  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.3

>(1)この状態でマクロを実行し・・・ とありますが、VBAで処理して良ければ、Find メソッド と FindNext メソッドを使うと良いでしょう。 双方をVBAのヘルプで調べて「使用例」を参考にすれば、ADOとか言っている方には比較的簡単な コードで出来ると思います。 また、ワークシート関数だけで、処理したい ということですと、例えば、Sheet1のD列を作業列とし、 セルD2に、B列の形式が文字列の場合は、=A2&B2 、日付形式の場合は、=A2&TEXT(B2,"yyyymm") を 設定し、下へコピーし、これをSheet2側で同じ方法でAとBを結合したものを検索値として、 VlookUp関数で検索し、C列を参照すれば良いでしょう。

nak777r
質問者

お礼

回答ありがとうございます なるほど、A列+B列の検索キーをD列に作るという考え方 は思いつきませんでした。 それであれば、Find関数はD列だけで住むので簡単ですね ありがとうございました。

noname#79209
noname#79209
回答No.2

ご要望の事柄は、エクセルの分野ではないように思えます。 むしろ、アクセス向きの仕事といえます。 唯一、エクセルらしい仕事は、数値の修正ですが、 これとて、アクセスのデータシート表示で可能です。 多分Sheet2は、毎回外部から取り込むのでしょうから、Sheet2にマクロを置く訳けにもいきませんし、 Sheet2の「値」を編集するので、数式を置く訳にもいきません。 まして、「全ての行をマクロでループさせるのは、遅くなるのであまりやりたくない」 ということなので、 回答者とすれば「どうせえちうんじゃ!」と言いたくなります。 となると、やはりアクセスの更新クエリと追加けりを使う方が良い思います。 「だって、アクセス持ってないモン。アクセス高いんモン」と言われたら、 それまでですか...

nak777r
質問者

お礼

回答ありがとうございます 実際は、この部分からさらに続きがありまして 最終的なものが、指定レイアウトに印字 そのレイアウトは既にEXCELにある状態なのです 基幹のデーターベースに無い1つのフィールドの為だけに アクセスを使用するのも馬鹿らしいので EXCELにデータのシートを持たせたいだけなのです。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

>Sheet1 の全ての行をマクロでループさせて >A列、B列をif分で比較し行を取得し、Sheet2 に張る場合、 >遅くなるのであまりやりたくないと思っています どの位のデータ数(行数)なのでしょう?

nak777r
質問者

お礼

データーは、月に30~100件ずつ増えていきます 1年位は持ちたいですが、基本は、私が重いと感じたら 手作業で古い年月から削除する予定です