[リストへもどる]
一括表示

投稿時間:2002/09/03(Tue) 10:22
投稿者名:さー
Eメール:
URL :
タイトル:
VB SQLで アクセステーブルを操作する
こんにちわ。VB始めたばかりの初心者です。
かなり煮詰まってしまったので分かる方よろしくお願いします。
(長くなってしまいましたが…)

現在、VBでアクセスのテーブルを操作しています。
給与計算において、休職者が出た時の日数計算をしています。
テーブル名が長いので略して書きます。

テーブルA 処理年月日や支給年月日などのテーブル
   a1(数値型ex.200208)…給与年月 a2(日付型)…支給年月日
テーブルB 計算した日数を入れるテーブル
   b1(数値型)・・社員コード b2(数値型)・・日数 b3(日付型)…支給年月日
テーブルC 休職情報が書かれたテーブル
   c1(数値型)…社員コード c2(日付型ex.02/08/25)…休職開始日

とします。

現在処理中の時、同月に休職者がいた場合、その月の日数から休職開始日の日にち引いて日数を求め
ます。
テーブルBには、テーブルCと同じ人がいるとは限りません。
もし、同じコードがある場合はb2だけを更新し、
一致しない場合はテーブルBに追加して、b1、b2、b3 全ての項目を追加します。
現在処理中のものがあるかどうかの判断と、もしあった場合の年月(aa とします。)は求めてありま
す。

現在処理中の時、その月の一日をx、末日をwとし、
x=DateSerial(Year(aa),Mnth(aa),1)
w=DateSerial(Year(aa),Month(aa)+1,0) と求めました。

b1=c1が一致する時
Excute "update B inner join C on B.b1=C.c1 " _
     & "set b2('& day(w) &' - day(C.c2))" _
     & "where (C.c2 Between # '& format(x,'yy/mm/dd') &' #" _
     & "and # '& format(w,'yy/mm/dd') '& #)"
b1=c1が一致しない時
Excute "insert into B (b1 b2 b3) " _
     & "select C.c1,'& day(w) &' - day(C.c2),A.a2
     & "from A,B inner join C on B.b1=C.c1 " _
     & "where ((C.c2 between C.c2 Between # '& format(x,'yy/mm/dd') &' #&q
uot; _
     & "and # '& format(w,'yy/mm/dd') '& #) " _
     & "and (B.b1 is null))

と書いたのですが、演算子が足りませんと出てしまいました。
長々となってしまいましたが、分かる方お願いします。

投稿時間:2002/09/03(Tue) 10:54
投稿者名:さー
Eメール:
URL :
タイトル:
Re: VB SQLで アクセステーブルを操作する
> と書いたのですが、演算子が足りませんと出てしまいました。

すみません。間違っていました。日付構文のエラーと出ました。
どのように直していいのか分かりません。
どなたかよろしくお願いします。
たびたびすみません。



※ この掲示板は後で修正ができますので、パスワードを保存して
  しておいて下さい。(管理人)

投稿時間:2002/09/03(Tue) 11:04
投稿者名:A221
Eメール:
URL :
タイトル:
Re^2: VB SQLで アクセステーブルを操作する
えーと、ここに転記するときに書き換えられたのでしょうか?
VBの構文エラーになりそうなのが多々あります。

再度SQLを投稿していただかないとわかんないです。

--------------------------------------------------------

>& "where (C.c2 Between # '& format(x,'yy/mm/dd') &' #" _
& "where (C.c2 Between #" & format(x,"yy/mm/dd") & "#&qu
ot; _

>& "and # '& format(w,'yy/mm/dd') '& #)"
& "and # " & format(w,"yy/mm/dd") & "#)"

>& "where ((C.c2 between C.c2 Between # '& format(x,'yy/mm/dd') &' #&
quot; _
& "where ((C.c2 between C.c2 Between #" & format(x,"yy/mm/dd") &a
mp; "#" _

>& "and # '& format(w,'yy/mm/dd') '& #) " _
& "and # " & format(w,"yy/mm/dd") & "#) " _

投稿時間:2002/09/03(Tue) 11:10
投稿者名:さー
Eメール:
URL :
タイトル:
Re^3: VB SQLで アクセステーブルを操作する
あ すみません。 コピペしてたらこんなことに…
Excute "update B inner join C on B.b1=C.c1 " _
& "set b2('& day(w) &' - day(C.c2))" _
& "where (C.c2 Between # '& format(x,'yy/mm/dd') &' #" _
& "and # '& format(w,'yy/mm/dd') '& #)"
b1=c1が一致しない時
Excute "insert into B (b1 b2 b3) " _
& "select C.c1,'& day(w) &' - day(C.c2),A.a2 " _
& "from A,B inner join C on B.b1=C.c1 " _
& "where ((C.c2 between C.c2 Between # '& format(x,'yy/mm/dd') &' # _
& "and # '& format(w,'yy/mm/dd') '& #) " _
& "and (B.b1 is null))

です 
よろしくおねがいします

投稿時間:2002/09/03(Tue) 11:33
投稿者名:A221
Eメール:
URL :
タイトル:
Re^4: VB SQLで アクセステーブルを操作する
シングルクォーテーションとダブルクォーテーションが入り混じっていますが、
投稿されたものを見る限りではここでは?
(INSERT UPDATE2行とも)
------------------------------------------------------
> & "and # '& format(w,'yy/mm/dd') '& #)"
                                   ^
& "and # '& format(w,'yy/mm/dd') & '#)"
                                   ^

投稿時間:2002/09/03(Tue) 11:41
投稿者名:さー
Eメール:
URL :
タイトル:
Re^5: VB SQLで アクセステーブルを操作する
さっそくの回答ありがとうございます。

> シングルクォーテーションとダブルクォーテーションが入り混じっていますが、

ということですが、それは多分違うと思います。
""←これは、SQL文を囲うもので、改行するたびにつけなくてはならないものです。
そこで、SQL文の中に""は使えないので、’を使用します。

多分これはあっていると思うのですが…

投稿時間:2002/09/03(Tue) 11:45
投稿者名:とろ
Eメール:
URL :
タイトル:
Re^6: VB SQLでアクセステーブルを操作
> > シングルクォーテーションとダブルクォーテーションが入り混じっていますが、
> ということですが、それは多分違うと思います。
いいえ、そこですよ。
w は VB での変数ですので、ダブルクォーテーションの外側に出す必要があります。

Execute のステートメントにブレイクポイントを設定して、
発行しているクエリをイミディエイトウィンドウに表示させてみて下さい。
そうすれば、どこが間違っているのか一目瞭然です。

# ちなみに、 データベースが Access の場合には、
# 例え、コンパネの日付の設定が yy/mm/dd であったとしても、
# 書式設定で yy/mm/dd とすると意外な結果になる可能性があるので、
# yyyy/mm/dd あるいは、 mm/dd/yy としましょう。
# http://www.microsoft.com/japan/support/kb/articles/JP416/0/56.asp

投稿時間:2002/09/03(Tue) 13:07
投稿者名:さー
Eメール:
URL :
タイトル:
Re^7: VB SQLでアクセステーブルを
変数は出さなきゃいけないんですね!!!
さっそくやってみました。
無事エラーが出ずに通りました!!!
ありがとうございます〜〜〜

しかし、アクセスのテーブルの値が全く動いていなかったのですが…

投稿時間:2002/09/03(Tue) 11:59
投稿者名:A221
Eメール:
URL :
タイトル:
Re^6: VB SQLで アクセステーブルを操作
えー、とろさんが先に回答されているので蛇足的になりますが、

まずUPDATE節が
---------------------------------------------------------
sqltmp = "update B inner join C on B.b1=C.c1 set b2("
sqltmp = sqltmp & Day(w) & " - day(C.c2)) "
sqltmp = sqltmp & "where (C.c2 Between # " & Format(x, "yy/mm/dd"
)
sqltmp = sqltmp & " #" & "and # " & Format(w, "yy/mm/dd&
quot;) & "#)"

でINSERT節が
---------------------------------------------------------
sqltmp = "insert into B (b1 b2 b3) " & "select C.c1,"
sqltmp = sqltmp & Day(w) & " - day(C.c2),A.a2 "
sqltmp = sqltmp & "from A,B inner join C on B.b1=C.c1 "
sqltmp = sqltmp & "where ((C.c2 between C.c2 Between # "
sqltmp = sqltmp & Format(x, "yy/mm/dd") & " #"" & &q
uot;and # "
sqltmp = sqltmp & Format(w, "yy/mm/dd") & "#) " & "and (
B.b1 is null))"

---------------------------------------------------------
こうなると思います。

文字列の合成なので、動作の効率的には悪いですが、
区切り文字と型ちがいとかのエラーがわかりやすいので
私はいつも上記のように書いてます。

Msgbox sqltmp
で、プログラム中に表示させることもできますし。

投稿時間:2002/09/03(Tue) 13:10
投稿者名:さー
Eメール:
URL :
タイトル:
Re^7: VB SQLでアクセステーブルを
長い文は分割しちゃうのですね。
たしかに見やすくなり、ミスが減るかも…
おっちょこちょいな私にはステキな方法です!!

ありがとうございました〜〜
エラーは出なくなったので、アクセステーブルの値がちっとも動いていない原因を模索してみます。

投稿時間:2002/09/03(Tue) 18:02
投稿者名:さー
Eメール:
URL :
タイトル:
Re: VB SQLで アクセステーブルを操作する
みなさんに助けられてエラーが出なくなりました。
しかし、全くデータが動いておらず、
アクセスクエリーで実行したところ、
データが表示されませんでした。

エラーが出ないので全くわかりません。
どなたか分かる方よろしくお願いします。

投稿時間:2002/09/03(Tue) 19:59
投稿者名:とろ
Eメール:
URL :
タイトル:
Re^2: VB SQLで アクセステーブルを操作する
> エラーが出ないので全くわかりません。

実際に発行しているクエリを載せて下さい。

投稿時間:2002/09/04(Wed) 09:39
投稿者名:さー
Eメール:
URL :
タイトル:
Re^3: VB SQLで アクセステーブルを操作する
クエリーは、debugしたものをそのまま入れてみました。

update B inner join C on B.b1 = C.c1 set b2=(31 - day(C.c2)) where (format(C.c2),'yyyy/mm/dd'
) between '2001/05/01' and '2001/05/31')

insert into B (b1,b2,b3) select C.c1,(31-day(C.c2)),A.a2 from A,B inner join C on B.b1 = C.c1
where ((format(C.c2,'yyyy/mm/dd') between '2001/05/01' and '2001/05/31') and (B.b1 is null))

です。よろしくおねがいします。

投稿時間:2002/09/04(Wed) 10:54
投稿者名:とろ
Eメール:
URL :
タイトル:
Re^4: VB SQLで アクセステーブルを操作する
update の方に関して、

() の位置が違います。
それ以外は大丈夫でしょう。

insert の方に関して、

まず、 B.b1, C.c1 は主キーとして考えて良いですよね?

> insert into B (b1,b2,b3)
> select C.c1, 31 - day(C.c2), A.a2
> from A, B inner join C on B.b1 = C.c1
> where format(C.c2, 'yyyy/mm/dd') between '2001/05/01' and '2001/05/31'
> and  B.b1 is null

・大きな問題点1
    恐らく、"B.b1 is null" の条件によって、
    B に存在しないと判断していると思うのですが、
    inner join (内部結合)を使っているので、
    そもそも、 "B.b1 is null" のレコードは抽出されません。
    やるならば、外部結合を使用して下さい。
    # それ以前に、 B に存在する場合は、 update の方に行って、
    # insert の方には来ないように、なっているのでは?
・大きな問題点2
    B と C との結合キーは記述されていますが、
    A との結合キーが記述されていません。
・どうでもいい点
    C.c2 (日付型)をわざわざ文字列に変換する必要はないのでは?

説明が下手なので分かりにくいかと思いますが、
分からなかったら再度質問して下さい。

投稿時間:2002/09/04(Wed) 11:41
投稿者名:さー
Eメール:
URL :
タイトル:
Re^5: VB SQLで アクセステーブルを操作する
updateについては、いろいろ模索していく中で無事きちんと通り、
データも動いているのを確認できました。
ありがとうございました。

> ・大きな問題点1
>     恐らく、"B.b1 is null" の条件によって、
>     B に存在しないと判断していると思うのですが、
>     inner join (内部結合)を使っているので、
>     そもそも、 "B.b1 is null" のレコードは抽出されません。
>     やるならば、外部結合を使用して下さい。
>     # それ以前に、 B に存在する場合は、 update の方に行って、
>     # insert の方には来ないように、なっているのでは?

なるほど・・・
Bに存在するものとしないものがあるので、存在するかどうかの判断はせずに
update〜 insert〜を書いていました。

> ・大きな問題点2
>     B と C との結合キーは記述されていますが、
>     A との結合キーが記述されていません。

結合させないと動かないんですか???

> ・どうでもいい点
>     C.c2 (日付型)をわざわざ文字列に変換する必要はないのでは?

えと、データが 02/09/04 という形なので、そのあとの between〜 にあわせて西暦4桁にしたかっ
たのですが、違う方法あるのでしょうか?

アドバイスを参考にもう一度やってみます。
ありがとうございました。

投稿時間:2002/09/04(Wed) 12:43
投稿者名:とろ
Eメール:
URL :
タイトル:
Re^6: VB SQLで アクセステーブルを操作する
> 結合させないと動かないんですか???

A に2レコード以上存在する場合は、
予期しない結果になる可能性があります。

> えと、データが 02/09/04 という形なので、そのあとの between〜
> にあわせて西暦4桁にしたかったのですが、違う方法あるのでしょうか?

恐らく、『 yyyy/mm/dd で指定して下さい』って
私が言ったからこのようにしたと思うのですが、
それは Microsoft のページを見れば分かりますが、
日付リテラルを使った( # で囲った)場合ですよ。

例えば、 Access のクエリで、
(#2001/02/03# < #2005/02/01#) は当然 True となりますが
(  #01/02/03# <   #05/02/01#) は False となってしまいます。
つまり、『 # の中身は年4桁で指定して下さい』という意味であって、
日付リテラルを使わずに、日付型のフィールドを直接記述する場合は、
年2桁とかは関係ありません。

> where format(C.c2, 'yyyy/mm/dd') between '2001/05/01' and '2001/05/31'
where C.c2 between #2001/05/01# and #2001/05/31#
                    ^^^^    と       ^^^^ の部分は4桁にして下さいという意味。

投稿時間:2002/09/04(Wed) 15:09
投稿者名:さー
Eメール:
URL :
タイトル:
Re^7: VB SQLでアクセステーブルを操作
> where C.c2 between #2001/05/01# and #2001/05/31#

これで実行してみたところ、
アクセスクエリーではデータが何も出てこなくて、
VBの方で実行させたところデータが全て消えてしまいました。

’’でやったら、うまくいったのでこっちでやってみたのですが・・・

投稿時間:2002/09/04(Wed) 16:06
投稿者名:とろ
Eメール:
URL :
タイトル:
Re^8:VB SQLでアクセステーブル・・
> ’’でやったら、うまくいったのでこっちでやってみたのですが・・・

C.c2 は日付型って最初に書いていましたけど、
実際はテキスト型ではないですか?

投稿時間:2002/09/04(Wed) 17:08
投稿者名:さー
Eメール:
URL :
タイトル:
VB SQLでアクセステーブル
テーブルを確認したところ日付型でした。
いま、insert文をいろいろ模索しているのですが、
そこでも#02/08/25# が、実際には 25/02/05 と表示されてしまいました。

投稿時間:2002/09/04(Wed) 17:36
投稿者名:とろ
Eメール:
URL :
タイトル:
VB SQLでアクセステ・・
> そこでも#02/08/25# が、実際には 25/02/05 と表示されてしまいました。

25/02/05 ?

日付型フィールドに #02/08/25# を insert すると、
Access のテーブルには、 25/02/08 と表示されるはずですよ。
(コンパネの日付の設定が yy/mm/dd の場合)