Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1575 / 2272 ツリー ←次へ | 前へ→

【6403】データベースから該当の複数データを抽出したい sayaya 05/10/4(火) 14:31 質問[未読]
【6410】Re:データベースから該当の複数データを抽出... 小僧 05/10/4(火) 16:47 発言[未読]
【6411】Re:データベースから該当の複数データを抽出... sayaya 05/10/5(水) 9:12 お礼[未読]
【6412】Re:データベースから該当の複数データを抽... 小僧 05/10/5(水) 9:37 回答[未読]
【6420】Re:データベースから該当の複数データを抽... sayaya 05/10/6(木) 9:13 お礼[未読]
【6421】Re:データベースから該当の複数データを抽... sayaya 05/10/6(木) 9:20 お礼[未読]
【6423】Re:データベースから該当の複数データを抽... 小僧 05/10/6(木) 9:48 回答[未読]
【6424】Re:データベースから該当の複数データを抽... sayaya 05/10/6(木) 10:06 お礼[未読]
【6425】Re:データベースから該当の複数データを抽... 小僧 05/10/6(木) 10:15 回答[未読]
【6436】Re:データベースから該当の複数データを抽... sayaya 05/10/7(金) 10:39 お礼[未読]
【6437】Re:データベースから該当の複数データを抽... 小僧 05/10/7(金) 11:10 回答[未読]
【6438】Re:データベースから該当の複数データを抽... sayaya 05/10/7(金) 12:19 お礼[未読]
【6439】Re:データベースから該当の複数データを抽... 小僧 05/10/7(金) 13:03 回答[未読]
【6440】Re:データベースから該当の複数データを抽... sayaya 05/10/7(金) 14:46 お礼[未読]
【6441】Re:データベースから該当の複数データを抽... 小僧 05/10/7(金) 15:13 発言[未読]
【6443】Re:データベースから該当の複数データを抽... sayaya 05/10/7(金) 18:06 質問[未読]
【6448】Re:データベースから該当の複数データを抽... 小僧 05/10/9(日) 9:16 発言[未読]

【6403】データベースから該当の複数データを抽出したい
質問  sayaya  - 05/10/4(火) 14:31 -

引用なし
パスワード
   お初にお目にかかりますm(_ _)mこちらをよく利用しているという友人から
紹介してもらい、訪問させていただきました。

早速なんですが、私は現在、実績入力のシステムを作っています
(商品の検査項目など)、検査の項目が21あって、その1つ1つにデータベースが存在
しています。つまり21個のデータベースがあります。

実績を登録するフォームと、修正するフォームがあり、それぞれデータをINSERTしたさいに、
データベースに処理区分をもうけており、それぞれ、新規登録は1、修正は2、削除は3とフラグをたてています。

ここからが自分が抱えている問題なのですが、
検査実績を帳票に表示するスプレッドを作りたいのですが,
一番最新の情報だけを表示する方法がわからないのです。

ただ、データの最新のものを、という単純なものならできるのですが、

説明がしにくいですので,仮のデータでお話しますと、

たとえば

日付2005/08/20、 通し番号 a1234、 連番001、 処理区分 1
  2005/08/20、      a1234、   002、      2
  2005/08/28、      a1234、   001、      3
  2005/08/20、      a5678、   003、     1
  2005/08/28、      a5678、   002、     2
  2005/08/20、      a9999、   004、     1

というレコードがあったとします、今回の帳票は、日付を指定して、
その日に行った検査データを表示するというものにしたいのですが、
このテストデータの中には2005/8/20、2005/08/28の日付が存在しますよね?

そこで帳票には、2005/08/20の実績には
2005/08/20   a9999  004  1 のデータ、
2005/08/28の帳票には
2005/08/28   a5678  002  2 のデータが表示されるようにしたいんです。

つまり、処理区分の3のものは帳票に載せない、
前日に実績があっても、翌日にデータを修正していたら(処理区分が2があったら)
前日の実績を帳票に載せないというのがしたいんです。

クエリを4つ作って、1、日付と連番をくっつける
       2、通し番号と1で作った日程連番をそれぞれ昇順と降順で並びかえる
       3、通し番号をグループ化して日程連番を最大のもので集計する
       4、処理区分が3のものを除く

という方法は思いついたのですが、何せよテーブルが21個もあるので、
それぞれにクエリを4つ作ったら,21×4で84個もテーブル、クエリが出来てしまうんです。

SQLでうまいこと出来ないかと思い、書いてみたのですが、
SELECT * FROM TEST WHERE (SYORI_KUBUN <> "3") ORDER BY TOSHIBANGO ASC, YYMMDD DESC, RENBAN DESC GROUP BY TOSHIBANGO HAVING Max([YYMMDD] + [RENBAN])

うまくいかず,,,

本当に困っています。どうか皆さんのお力をお借りできないでしょうか?

長文申し訳ありません。

【6410】Re:データベースから該当の複数データを抽...
発言  小僧  - 05/10/4(火) 16:47 -

引用なし
パスワード
   ▼sayaya さん:
こんにちは。

>前日に実績があっても、翌日にデータを修正していたら(処理区分が2があったら)
>前日の実績を帳票に載せないというのがしたいんです。

この「前日」「翌日」という使い方が良く解らないのですが、
翌日以降に修正があった場合は実績にならない、という事なのでしょうか?

言い換えると

通し番号ごとに、
処理区分 3 があった場合は対象外
処理区分 2 があった場合は最新の日付
処理区分 1 しかなかった場合はその日付

が抽出できれば良いのでしょうか。それでしたら

SELECT P.TOSHIBANGO,
    P.S_MAX,
    Max(TEST.YYMMDD) AS YYMMDDの最大
FROM [
SELECT TEST.TOSHIBANGO,
    Max(TEST.SYORI_KUBUN ) AS S_MAX
FROM TEST
GROUP BY TEST.TOSHIBANGO
]. AS P
INNER JOIN TEST ON (P.S_MAX = TEST.SYORI_KUBUN) AND
          (P.TOSHIBANGO = TEST.TOSHIBANGO)
GROUP BY P.TOSHIBANGO, P.S_MAX
HAVING P.S_MAX=1 Or P.S_MAX=2;

こんな感じで抽出ができると思います。


※半角カタカナは環境によって文字化けしてしまう事があるそうです。
 Web上の掲示板等をご利用される時はなるべく使わないように気をつけましょう^^

【6411】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/5(水) 9:12 -

引用なし
パスワード
   ▼小僧 さん:
返信ありがとうございます!!

前日、翌日、分かりにくかったですね、ごめんなさい。

つまり、小僧さんがおっしゃる通り、
処理区分3は対象外、
処理区分2が存在している通し番号に関しては、YYMMDDとRENBANが一番最新のもの、
処理区分1のものはそのままで抽出
ということです。

いただいたSQLのなかで分からないところがあったのですが、

>SELECT P.TOSHIBANGO,
>    P.S_MAX,
>    Max(TEST.YYMMDD) AS YYMMDDの最大
>FROM [
>SELECT TEST.TOSHIBANGO,
>    Max(TEST.SYORI_KUBUN ) AS S_MAX
>FROM TEST
>GROUP BY TEST.TOSHIBANGO
>]. AS P
>INNER JOIN TEST ON (P.S_MAX = TEST.SYORI_KUBUN) AND
>          (P.TOSHIBANGO = TEST.TOSHIBANGO)
>GROUP BY P.TOSHIBANGO, P.S_MAX
>HAVING P.S_MAX=1 Or P.S_MAX=2;

このなかの、P.TOSHIBANGOとP.S_MAXはほかのテーブルということでしょうか?

【6412】Re:データベースから該当の複数データを抽...
回答  小僧  - 05/10/5(水) 9:37 -

引用なし
パスワード
   ▼sayaya さん:
おはようございます。

>>SELECT P.TOSHIBANGO,
>>    P.S_MAX,
>>    Max(TEST.YYMMDD) AS YYMMDDの最大
>>FROM [
>>SELECT TEST.TOSHIBANGO,
>>    Max(TEST.SYORI_KUBUN ) AS S_MAX
>>FROM TEST
>>GROUP BY TEST.TOSHIBANGO
>>]. AS P
>>INNER JOIN TEST ON (P.S_MAX = TEST.SYORI_KUBUN) AND
>>          (P.TOSHIBANGO = TEST.TOSHIBANGO)
>>GROUP BY P.TOSHIBANGO, P.S_MAX
>>HAVING P.S_MAX=1 Or P.S_MAX=2;

>このなかの、P.TOSHIBANGOとP.S_MAXはほかのテーブルということでしょうか?

この P は任意の名前で大丈夫です。
FROM 句 の中に SELECT 〜 でもう一つ SQL を使用していますが、
([ ] に 囲まれた部分です) その結果を AS P という形で別名をつけています。

※ クエリの SQL ビューに貼り付ける際は全角スペースが入ってしまう場合が
  あるので取り除いてください。


>処理区分2が存在している通し番号に関しては、YYMMDDとRENBANが一番最新のもの

日付だけを抽出するのであれば、RENBAN が最新かどうかの判定が必要ないので
上記の SQL では RENBAN を考慮していません。

>>>YYMMDD    TOSHIBANGO   SYORI_KUBUN   RENBAN 
>>>2005/10/05   a1234        2      1   
>>>2005/10/05   a1234        2      2   

>>REBAN がいくつであろうが、最新が2005/10/05である事には変わりがない。


実際に使用されているデータが連番ごとに違う値…

>>>YYMMDD    TOSHIBANGO   SYORI_KUBUN   RENBAN  NAMAE
>>>2005/10/05   a1234        2            1     山田
>>>2005/10/05   a1234        2            2     佐藤

上記のように NAMAE のような値も抽出対象になるようでしたら、
通し番号も含めた SQL にしなければいけないですね。

その場合は再度考えたいと思います。

【6420】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/6(木) 9:13 -

引用なし
パスワード
   ▼小僧 さん:
おはようございます。

えっと、、通し番号が、ひとつの"物"と考えたとき、
連番とは、その日に検査した総数(つまり検査をカウントしている)を表しています。

ですので,
a1234 という製品を、初回検査日が2005/08/20で、2005/08/29に3回再検査したとすれば、
通し番号  日付      連番   処理区分
a1234    2005/08/20   001     1
a1234    2005/08/29   001     2
a1234    2005/08/29   002     2
a1234    2005/08/29   003     2

というデータができ、

製品の検査実績としては、
日付が一番最新で、なおかつ最後に検査された(連番が003)、処理区分が2
のものが抽出したいということです。

つまり
a1234   2005/08/29    003   2
のレコードが抽出されればよいのですが、うまくいきません。

【6421】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/6(木) 9:20 -

引用なし
パスワード
   ▼小僧 さん:
追伸、先ほどの場合は、ひとつの通し番号(製品)でしたが、
実際のテーブルには、たくさんの通し番号をもつレコードが存在しています。

ですので、通し番号をグループ化して、なおかつ、日付と連番の最大値を抽出
させることが重要なのですが、21個も違う検査内容のテーブルが存在しているため、
クエリをあまり作ることができないのです。

抽出はひとつのテーブル内の話です!ただ、同じ作業を21項目するので、
総容量がでかくなりアプリの動きがかなり鈍くなることが予想できて・・・


容量をあまり食わない回避策がありますでしょうか?

【6423】Re:データベースから該当の複数データを抽...
回答  小僧  - 05/10/6(木) 9:48 -

引用なし
パスワード
   ▼sayaya さん:
おはようございます。

SQL についてはちょっと考え中なのでもう少し待ってください ^^;

>クエリをあまり作ることができないのです。
>容量をあまり食わない回避策がありますでしょうか?

クエリの実態は SQL なので、クエリを作成しなくても
SQL で呼び出すことは可能です。

具体的な例をあげてみましょう。


SELECT * FROM TEST
この SQL を「クエリA」として保存します。

クエリAを元にフォームを作成します。(表形式が解りやすいかもです)
適当な名前をつけて保存します。

作成したフォームのレコードソースは「クエリA」となっている筈です。
ここを「SELECT * FROM TEST」 と置き換えます。

クエリA を削除しても、フォームに結果は表示されると思います。


繰り返しになってしまいますが、クエリの実態は SQL なので
わざわざ作成しなくても大丈夫ですよ。

【6424】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/6(木) 10:06 -

引用なし
パスワード
   ▼小僧 さん:
なるほど、てっきり作成しなくてはならないかと思っていました。
私ももう少し考えてみます。
小僧さんも,なにかよいアイデアが浮かびましたら、
お助けいただければ幸いです。
ありがとうございます。

【6425】Re:データベースから該当の複数データを抽...
回答  小僧  - 05/10/6(木) 10:15 -

引用なし
パスワード
   ▼sayaya さん:
こんにちは。

ロジックを考えていたのですが、もっと楽になりそうですね。

>1: 新規 2: 修正 3: 削除

ですから、同一通し番号において 3 の後に 2 や 1 が来たりはしませんよね?

なので最新の日付の最大の処理区分で判断できそうですね。
  3  でしたら 対象外、
2 や 1 でしたら 最大のREBAN

を抽出すれば良さそうです。

SELECT P.日付, P.通し番号, P.処理区分, Max(TEST.RENBAN) AS 連番
FROM [
SELECT Max(TEST.YYMMDD) AS 日付, TEST.TOSHIBANGO AS 通し番号,
Max(TEST.SYORI_KUBUN) AS 処理区分
FROM TEST
GROUP BY TEST.TOSHIBANGO
]. AS P
INNER JOIN TEST
ON (P.処理区分 = TEST.SYORI_KUBUN) AND
(P.通し番号 = TEST.TOSHIBANGO) AND (P.日付 = TEST.YYMMDD)
GROUP BY P.日付, P.通し番号, P.処理区分
HAVING P.処理区分<>3;

上記 SQL をクエリの SQL ビューに貼り付けて結果を確認されてみて下さい。

【6436】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/7(金) 10:39 -

引用なし
パスワード
   ▼小僧 さん:
おはようございます。
本当にありがとうございます。
SQLビューに貼り付けてみたのですが、
>抽出条件でデータ型が一致しません。
というエラーがでてしまいました。。

私のやり方が間違ってるっぽいです泣

でも、ロジックは理解できました!

【6437】Re:データベースから該当の複数データを抽...
回答  小僧  - 05/10/7(金) 11:10 -

引用なし
パスワード
   ▼sayaya さん:
こんにちは。

>>抽出条件でデータ型が一致しません。

SQL を見直してみたのですが、怪しいのは下記の部分ですね。

HAVING P.処理区分<>3;

処理区分が数値型と判断させて頂いたのでこうなっていますが、もしテキスト型であれば

HAVING P.処理区分<>'3';

となります。

【6438】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/7(金) 12:19 -

引用なし
パスワード
   ▼小僧 さん:
以下の方法で表示できました!!!

しかし、あとひとつ問題があるのです、、、実は,
日付、通し番号、連番、処理区分のほかにも、A、B、C…と
検査実績のフィールドがあるんです。

このフィールドの値はすべてユニークなものなので、グループ化は
してはいけないですので、sqlではエラーになってしまいます。
実際のデータベースは、
日付    通し番号  連番   A    B    C    処理区分
05/10/07  a1234   001   abc   def   ghi     1
05/10/07  a1234   002   aac   ddd   ghi     2
05/10/07  b3456   003   jkl   mno   pqr     1
05/10/07  c5678   004   stu   vwx   yzz     1
05/10/07  b3456   005   jkl   mno   pqr     3
05/10/10  a1234   001   aaa   bbb   ccc     2

見たいな感じで,A、B、Cなどのフィールドもあるんですよね。
いっしょにここも抽出させたいのですが、出来るでしょうか?

【6439】Re:データベースから該当の複数データを抽...
回答  小僧  - 05/10/7(金) 13:03 -

引用なし
パスワード
   ▼sayaya さん:
こんにちは。

>このフィールドの値はすべてユニークなものなので、グループ化は
>してはいけないですので、sqlではエラーになってしまいます。

サブクエリ([ ] で括られた中)で
日付、通し番号、処理区分でグループ化しているため、
そのままユニークなフィールドも連結できますよ^^

SELECT
P.日付,
P.通し番号,
P.処理区分,
Max(TEST.RENBAN) AS 連番,
TEST.KENSA_A AS A,
TEST.KENSA_B AS B,
TEST.KENSA_C AS C
FROM [
SELECT
Max(TEST.YYMMDD) AS 日付,
TEST.TOSHIBANGO AS 通し番号,
Max(TEST.SYORI_KUBUN) AS 処理区分
FROM TEST
GROUP BY TEST.TOSHIBANGO
]. AS P
INNER JOIN TEST
ON (P.日付 = TEST.YYMMDD)
AND (P.通し番号 = TEST.TOSHIBANGO)
AND (P.処理区分 = TEST.SYORI_KUBUN)
GROUP BY
P.日付,
P.通し番号,
P.処理区分,
TEST.KENSA_A,
TEST.KENSA_B,
TEST.KENSA_C
HAVING (((P.処理区分)<>'3'));


KENSA_A、KENSA_B、KENSA_C というフィールド名を適宜変更してください。

【6440】Re:データベースから該当の複数データを抽...
お礼  sayaya  - 05/10/7(金) 14:46 -

引用なし
パスワード
   ▼小僧 さん:
いつもお返事ありがとうございますm(_ _)m


ちょっと追加フィールドが多すぎて,VB上に書くのが無理みたいなので、、、

最初に教えてくださった、
>SELECT P.日付, P.通し番号, P.処理区分, Max(TEST.RENBAN) AS 連番
>FROM [
>SELECT Max(TEST.YYMMDD) AS 日付, TEST.TOSHIBANGO AS 通し番号,
>Max(TEST.SYORI_KUBUN) AS 処理区分
>FROM TEST
>GROUP BY TEST.TOSHIBANGO
>]. AS P
>INNER JOIN TEST
>ON (P.処理区分 = TEST.SYORI_KUBUN) AND
>(P.通し番号 = TEST.TOSHIBANGO) AND (P.日付 = TEST.YYMMDD)
>GROUP BY P.日付, P.通し番号, P.処理区分
>HAVING P.処理区分<> '3' ;

のSQLで、日付と、連番を結合させてYYMMDDRENBAN を作りたいのですが、可能でしょうか?
そうすると、YYMMDDRENBANの最大と、TOSHIBANGOのグループ化、SYORI_KUBUN <> 3でレコードをしぼれますよね?P.YYMMDDERNBANとして取得可能でしょうか?

【6441】Re:データベースから該当の複数データを抽...
発言  小僧  - 05/10/7(金) 15:13 -

引用なし
パスワード
   ▼sayaya さん:
こんにちは。

>日付と、連番を結合させてYYMMDDRENBAN を作りたい

こちらについてはこんな感じでしょうか?

SELECT Max([P].[日付] & "_" & [TEST].[RENBAN]) AS 日付連番,
P.通し番号, P.処理区分
FROM [
SELECT Max(TEST.YYMMDD) AS 日付, TEST.TOSHIBANGO AS 通し番号,
Max(TEST.SYORI_KUBUN) AS 処理区分
FROM TEST
GROUP BY TEST.TOSHIBANGO
]. AS P
INNER JOIN TEST ON (P.日付 = TEST.YYMMDD)
AND (P.通し番号 = TEST.TOSHIBANGO)
AND (P.処理区分 = TEST.SYORI_KUBUN)
GROUP BY P.通し番号, P.処理区分
HAVING P.処理区分<>'3';


>ちょっと追加フィールドが多すぎて,VB上に書くのが無理みたいなので、、、

こちらがちょっと解らないのですが、
クエリのデザインビューの枠が足りない、という事なのでしょうか。

それとも文字通り VBA 上で SQL を作成しているという事なのでしょうか。

【6443】Re:データベースから該当の複数データを抽...
質問  sayaya  - 05/10/7(金) 18:06 -

引用なし
パスワード
   ▼小僧 さん:
こんばんは、小僧さん。

>>ちょっと追加フィールドが多すぎて,VB上に書くのが無理みたいなので、、、
>
>こちらがちょっと解らないのですが、
>クエリのデザインビューの枠が足りない、という事なのでしょうか。
>
>それとも文字通り VBA 上で SQL を作成しているという事なのでしょうか。

私はVB上にSQLを記入していますよ!
ですので、SQLに文字制限があるとか…?たしか255文字までと
聞いたのですが。。

【6448】Re:データベースから該当の複数データを抽...
発言  小僧  - 05/10/9(日) 9:16 -

引用なし
パスワード
   ▼sayaya さん:
おはようございます。

>SQLに文字制限があるとか…?たしか255文字までと
>聞いたのですが。。

当方が実際に業務で使っている SQL は軽く255文字を突破していますね。
(650文字前後の SQL があります。)

strSQL = "SELECT ・・・・ " _
    & "FROM ・・・・"

のように1行に納めずに改行コードを使っていけば
255文字以上の SQL も普通に発行できると思うのですがいかがでしょうか。

1575 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078242
(SS)C-BOARD v3.8 is Free