[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『エクセルのプログラム(?)についてどなたか教えてください。』(てつ)
シート1に、200人の社員リストを作りました。社員番号をA列に、氏名をB列に並べました。 シート2に、講習会に出席した人の社員番号を入力しVLOOKUP関数で右列に氏名が出るようにしました。 そこで、シート3に、講習会に出席してない人の社員番号を自動的に表示させたいのです。 どのような考え方、関数、マクロを使用すればよいのでしょうか? どなたか教えてください。エクセルは2003です。
INDEX、SMALL、MATCH、ROWなど組み合わせると出来そうですね。 レイアウト提示がないと具体的にはお示しできませんが。
マクロであれば、Dictionaryを使えば簡単に出来そうです。 社員リストすべてをDictionaryにセットして、出席した人をRemoveします。 残ったKeyを出力すればOKです。
(ROUGE)
レイアウト提示というと、
シート1には元データとも言うべきデータを入力してあります。数字は社員番号です。
A B 001 鈴木太郎 002 山下啓二 003 飯田雅彦 004 大田良治 005 小山憲一
シート2では、講習会に出席した人を入力します。
社員番号を入力すると、
if(a1="","",vlookup(a1,a1:b5,1,false))という関数で氏名を表示させています。
A B 002 山下啓二 003 飯田雅彦 005 小山憲一
シート3のa1からa50まで上から社員番号順に表示させたいのです。
いかがでしょうか?
尚、マクロにもとても興味があります。
お手間でなければ、コードを教えていただけるとうれしいです。
=IF(COUNTA(Sheet1!$A$1:$A$10)-COUNTA(Sheet2!$A$1:$A$10)<ROW(A1),"", INDEX(Sheet1!$A$1:$A$10,SMALL(IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),""),ROW(A1)))) と入力して、Ctrl+Shift+Enterで数式を確定。 必要分下にフィルドラッグします。 名前はVLOOKUP関数で表示してください。
マクロならばこんな感じ。 (ROUGE) '---- Sub test() Dim dic As Object Dim tbl, ky Dim i As Long With Sheets("Sheet1") tbl = .Range("A1", .Range("A" & Rows.Count).End(xlUp)).Resize(, 2).Value End With Set dic = CreateObject("Scripting.Dictionary") For i = 1 To UBound(tbl, 1) ky = tbl(i, 1) & "_" & tbl(i, 2) dic(ky) = Empty Next With Sheets("Sheet2") tbl = .Range("A1", .Range("A" & Rows.Count).End(xlUp)).Resize(, 2).Value End With For i = 1 To UBound(tbl, 1) ky = tbl(i, 1) & "_" & tbl(i, 2) If dic.Exists(ky) Then dic.Remove ky End If Next With Sheets("Sheet3") .Range("A:B").ClearContents If dic.Count > 0 Then i = 0 For Each ky In dic.keys i = i + 1 .Range("A" & i).Resize(, 2).Value = Split(ky, "_") Next End If End With Set dic = Nothing End Sub
シート名や、社員数の部分の数字などを変更して張付けてみました。
見ましたが、うまくいきません。
上の例は簡単にするために簡略化したのですが、
実物は、社員データのシートは別に。
出席した人を書き込むシートと、
出席していない人を表示させるシートは
同じシートにしたのです。
これが原因でしょうか?
もしよければ、この関数プログラムの解説をしていただくわけにはいきませんか?
どういう考え方で、どういう流れでこういうプログラムとなるのかを知りたいのです。
これがわかれば、自分のプログラム上で応用できそうな気がします。
よろしくお願いします。
てつ
=IF(COUNTA(Sheet1!$A$1:$A$10)-COUNTA(Sheet2!$A$1:$A$10)<ROW(A1),"", INDEX(Sheet1!$A$1:$A$10,SMALL(IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),""),ROW(A1)))) まず、IF関数の部分。 COUNTA(Sheet1!$A$1:$A$10)-COUNTA(Sheet2!$A$1:$A$10)<ROW(A1) リストに記載されている人数から出席した人数を引いた数、即ち欠席した人数が、行数よりも少ないときは空白を返す。 そうでない場合はINDEX(・・・の結果を返す、というものです。 次はこの関数のコア部分はINDEXの部分ですので、その解説です。 INDEX(Sheet1!$A$1:$A$10,SMALL(IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),""),ROW(A1))) Sheet1のリストからSMALL(・・・)で得られる数字の順番のものを返すというものです。 SMALL(IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),""),ROW(A1)) これは、IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),"")で得られる 数値の配列から小さい順に数値を返すというものです。 IF(ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)),ROW($A$1:$A$10),"") ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0))がTrueの場合、それぞれの順番に合った数値を返すというものです。 ISERROR(MATCH(Sheet1!$A$1:$A$10,Sheet2!$A$1:$A$10,0)) Sheet1のリストの人でSheet2の出席者名簿に名前がない場合、Trueを返します。 といった構造になっています。 (ROUGE)
ありがとうございます。又、ぜひ質問させて下さい。
(てつ)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.