Access VBA質問箱 IV

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

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


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

【11706】データのないフィールドの表示 MIT48 10/7/5(月) 23:41 質問[未読]
【11707】Re:データのないフィールドの表示 小僧 10/7/6(火) 9:58 発言[未読]
【11708】Re:データのないフィールドの表示 MIT48 10/7/6(火) 20:01 発言[未読]
【11709】Re:データのないフィールドの表示 小僧 10/7/6(火) 23:39 回答[未読]
【11733】Re:データのないフィールドの表示 MIT48 10/7/13(火) 18:53 発言[未読]
【11734】Re:データのないフィールドの表示 小僧 10/7/14(水) 8:35 回答[未読]
【11739】Re:データのないフィールドの表示 MIT48 10/7/17(土) 15:07 発言[未読]

【11706】データのないフィールドの表示
質問  MIT48  - 10/7/5(月) 23:41 -

引用なし
パスワード
   ACCESSで行き詰ったので質問させてください(>_<)


各支店の伝票を集計するツールを作成しているところなのですが・・・

完成イメージは下のようなカンジです↓

〔図1〕完成テーブル

   21 22 23 24 25 26 27 28 29 30      16 17 18 19 20
101| 3| 4|34| 7| | | | 6|45| 8|・・・| 6| | | | |
102| 4|34|21| 8| 4| | |27|32| 4|   |35|21| | |21|
103| |56| |10|64| | | |56| |   |17| | | | |
104| |59| | |43| | |67| | |   |98|65| | |46|
105|54|34|37|24|36| | |64|68|24|   |13|25| | |28|
106|38|46|57|53|47| | | |43|57|   |45|67| | |54|
106|78|65|43|65|78| | |32| 6| 8|   |23| 4| | | 5|
107| | 5| 7| 8| 2| | | 5|21| 1|   |12|11| | | 9|
108|12| 4|34|21| 1| | | 7|86|54|   |32| 4| | | 9|

フィールドに月度日付のみ表示(20日締めなので21日〜20日)
列見出しに支店コード(101〜108)
伝票番号をカウントしてクロス集計で表にした状態でエクセルにエクスポートしたいのです。


元データは[売上テーブル]

〔図2〕売上テーブル

 支店|伝票番号|売上計上日
 107 |********|20100620
 105 |********|20100621
 103 |********|20100623
 101 |********|20100623
 101 |********|20100624
 109 |********|20100625
 104 |********|20100625
 103 |********|20100625
 105 |********|20100625
 104 |********|20100628
       :
       : 
 102 |********|20100717
 105 |********|20100717
 104 |********|20100717
 106 |********|20100720
 104 |********|20100720
 105 |********|20100720

この元データは1週間ずつしか取得できないので、追加クエリで[売上テーブル]にデータはためていくようにします。
上のは月度、一月分が集計し終わった状態です。


これだけあれば普通に集計クエリでいけると思うのですが


〔図3〕現状の完成テーブル

   <> 21 22 23 24 27 28 29      16 17 20
101| 0| | | | | | | |・・・| | | |
102| |34|21| 8| 4|27|32| 4|   |35|21|21|
103| |56| |10|64| |56| |   |17| | |
104| |59| | |43|67| | |   |98|65|46|
105| |34|37|24|36|64|68|24|   |13|25|28|
106| 0| | | | | | | |   | | | |
106| 0| | | | | | | |   | | | |
107| | 5| 7| 8| 2| 5|21| 1|   |12|11| 9|
108| | 4|34|21| 1| 7|86|54|   |32| 4| 9|


問題となっているのは休日です。
〔図1〕のように休日は空欄として表示させたいのですが、クロス集計を使うとデータのないところは表示されませんでした。
これは列見出しの支店でも同じでした。
〔図2〕の元データ[売上テーブル]にも休日は集計されません。

列見出しの支店は別に[支店テーブル]を用意して、クロス集計のときに[支店テーブル]を結合させて結合プロパティを設定することでどうにかなったのですが・・・

〔図3〕のように一番左に伝票のなかった支店の0が表示される<>フィールドができてしまいます。


説明下手なうえ長くなりましたが、今解決したいことは

・データのない休日フィールドを表示させる。
・<>の0が表示されるのを表示させない。

〔図1〕の完成形になればいいのですが・・・欲をいうと

・一番右のフィールドには合計フィールドを追加

も検討しています。

作るのは私ですが、使うのは支店の方なのでできるだけ余計な手間を省きクエリだけでなんとかしたいと思っています。
私自身もACCESSはさわって1ヶ月なので用語やSQLなどはわからないところだらけです。
初歩的な質問わけのわからない質問をしてしまうことがあるかと思いますがみなさんにご教授お願いいたしますm(__)m

またこの掲示板のルール等もわからないので説明不足や失礼があったら申し訳ございません。

【11707】Re:データのないフィールドの表示
発言  小僧  - 10/7/6(火) 9:58 -

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

> 使うのは支店の方なのでできるだけ余計な手間を省き
> クエリだけでなんとかしたいと思っています。

使うのが別の方であれば尚更テーブルやクエリや見せずに
フォーム上に配置したコマンドボタン等にて操作して頂くのが
一般的だと思われるのですがいかがでしょうか。

使って頂く方の操作の手間を省くためには
MIT48 さんが相応の手間を掛けないと難しいかと思われます。


> 各支店の伝票を集計するツールを作成している
> エクセルにエクスポートしたい

仕様についてですが、
最終目的の Excelに Export ができるだけで良いのか、
それとも 今後も Access の ツールとして
色々データ操作をされたいのかによって
回答の内容も変わりますので教えて下さい。

また、列見出しについての仕様も
ご提示して頂ければと思います。

例えば2010年6月の場合、31日は存在しないため
… 29 30 1 2 …
としたいのか、それとも列見出しは31個固定で
… 29 30 31 1 2
で良いのかによって作りが多少変わって来ますね。


クロス集計クエリを使う上では
行見出しの扱いに注意する必要があります。

ミニミニ Access Tips
フィールド、コントロール、オブジェクトや変数などに付ける「名前」について
h tp://ww3.tiki.ne.jp/~kaya/Ac_tips.html#Tips0_001

上記サイトにもありますが、
テーブル(クエリ)のフィールドには

> 先頭に半角数字は使用しない

という様なお約束があります。
クロス集計クエリで日付をそのまま行見出しにした場合、
上記のタブーを犯してしまう事になります。

> フィールド名は、上記のタブーを犯していても場合によっては
> フィールド名の前後を [ ] で囲むことで回避できることもあります。

とある通り、注意すれば防げる事項なので
絶対にしてはいけない訳ではありませんが、

例えばクロス集計クエリの中から
更に20日のデータだけ欲しい、などという場合

SELECT 20 FROM クロス集計クエリ
SELECT [20] FROM クロス集計クエリ

2つのクエリ(SQL)は違う結果を返す事になりますので
注意が必要になります。

同様に

SELECT 2010/6/20 FROM クロス集計クエリ



SELECT 2000 ÷ 6 ÷ 20 FROM クロス集計クエリ

と解釈される恐れがあるので注意です。

【11708】Re:データのないフィールドの表示
発言  MIT48  - 10/7/6(火) 20:01 -

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

仕事中は返信ができないので家でになってしまいました
遅くなり申し訳ありませんm(__)m


説明不足ですみません(><)
補足させていただきます。

>使うのが別の方であれば尚更テーブルやクエリや見せずに
>フォーム上に配置したコマンドボタン等にて操作して頂くのが
>一般的だと思われるのですがいかがでしょうか。

フォームで作ることを考えて、使用者がクエリやテーブルにはさわらないように作成したいとかんがえております。
フォームだけは先に作ってしまってるのであとは中身を完成させなければというところです・・・

かなりの手間をかける覚悟もできております。


>仕様についてですが、
>最終目的の Excelに Export ができるだけで良いのか

最終的には毎月ごとにEXCELにExportできるまでで大丈夫です。
テーブルは集計が終わるごとに内容は削除できるようにし、次の月からはまた新しくデータを集めて集計という形にしようと考えています。


>また、列見出しについての仕様も
>ご提示して頂ければと思います。
>
>例えば2010年6月の場合、31日は存在しないため
>… 29 30 1 2 …
>としたいのか、それとも列見出しは31個固定で
>… 29 30 31 1 2
>で良いのかによって作りが多少変わって来ますね。

列見出しについてですが、小僧さんのおっしゃったところで悩んだんです!
いろいろ調べたのですがよくわからなくなり、うるう年があったらもっと大変みたいなことしかわかりませんでした・・・
できれば毎月ごとに自動で31があったりなかったりにできる仕様が理想なのですが・・・可能でしょうか?

現時点では31日を固定してある仕様にしておこうと考えていました。


>クロス集計クエリを使う上では
>行見出しの扱いに注意する必要があります。

ご忠告ありがとうございます。
いろいろ調べる過程で行見出しや列見出しの決定の仕方が重要なようだというのはわかっていたのですが・・・これから勉強していこうと思います。


まだまだ説明不足な部分があるかと思いますが、あればご指摘してください。
よろしくお願いいたします。

【11709】Re:データのないフィールドの表示
回答  小僧  - 10/7/6(火) 23:39 -

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

> フォームで作ることを考えて

という事ですので、VBAを使って回答させて頂きますね。

まずは準備としてテーブルの仕様固めからです。

先にご提示頂いた売上テーブルについてなのですが、
一番上のレコード

>  107 |********|20100620



> (20日締めなので21日〜20日)

という事なので存在してはいけないという事で大丈夫でしょうか?

今後の作業で 右2桁を持って日付とする様な操作が出て来るので
20100620 と 20100720 が同時に存在していると
同じ「20」という日付で集計されてしまいます。


次に

> 支店テーブル

が存在するという事ですので、

支店コード    支店名
101        A支店
102        B支店
103        C支店

の様なデータの持たせ方をして
売上テーブルは「支店コード」で管理してみましょう。

支店コード|伝票番号|売上計上日
--------------------------------
105    |********|20100621
103    |********|20100623


テーブルの準備が整いましたら VBA の出番です。

Sub MakeCrossQuery()
Dim strSQL As String
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim QD As DAO.QueryDef

  Set DB = CurrentDb
  
  'クエリ Q_Cross の存在チェック
  'なかった場合には作成
  'あった場合には使いまわし
  
  strSQL = " SELECT * FROM MsysObjects WHERE NAME ='Q_Cross'"
  
  Set RS = DB.OpenRecordset(strSQL, dbOpenSnapshot)
  If RS.EOF Then
    Set QD = DB.CreateQueryDef("Q_Cross")
  Else
    Set QD = DB.QueryDefs("Q_Cross")
  End If
  RS.Close
  
  'クロス集計クエリの作成
  
  strSQL = ""
  strSQL = strSQL & " TRANSFORM Count(売上テーブル.伝票番号) AS 伝票番号のカウント "
  strSQL = strSQL & " SELECT 売上テーブル.支店コード "
  strSQL = strSQL & " FROM 売上テーブル "
  strSQL = strSQL & " GROUP BY 売上テーブル.支店コード "
  strSQL = strSQL & " PIVOT Right([売上計上日],2);"

  QD.SQL = strSQL
  QD.Close
  
  MsgBox "クロス集計クエリ作成終了"

End Sub


上記をコピーし、標準モジュールに貼り付け実行させた後
クエリ「Q_Cross」が出来る事を確認してみて下さい。


ここまで出来ましたら段々と

> 伝票のなかった支店
>毎月ごとに自動で31があったりなかったりにできる仕様

に対応して行こうと思います。

【11733】Re:データのないフィールドの表示
発言  MIT48  - 10/7/13(火) 18:53 -

引用なし
パスワード
   ▼小僧 さん:

こんにちは。
ほかの仕事に追われなかなか手がつけられず返信できませんでした。
申し訳ありません・・・

時間があいてしまったのですが

> (20日締めなので21日〜20日)
>
>という事なので存在してはいけないという事で大丈夫でしょうか?

はい。記入ミスですので21日〜20日のフィールドでお願いします。


>
>Sub MakeCrossQuery()
>Dim strSQL As String
>Dim DB As DAO.Database
>Dim RS As DAO.Recordset
>Dim QD As DAO.QueryDef
>
>  Set DB = CurrentDb
>  
>  'クエリ Q_Cross の存在チェック
>  'なかった場合には作成
>  'あった場合には使いまわし
>  
>  strSQL = " SELECT * FROM MsysObjects WHERE NAME ='Q_Cross'"
>  
>  Set RS = DB.OpenRecordset(strSQL, dbOpenSnapshot)
>  If RS.EOF Then
>    Set QD = DB.CreateQueryDef("Q_Cross")
>  Else
>    Set QD = DB.QueryDefs("Q_Cross")
>  End If
>  RS.Close
>  
>  'クロス集計クエリの作成
>  
>  strSQL = ""
>  strSQL = strSQL & " TRANSFORM Count(売上テーブル.伝票番号) AS 伝票番号のカウント "
>  strSQL = strSQL & " SELECT 売上テーブル.支店コード "
>  strSQL = strSQL & " FROM 売上テーブル "
>  strSQL = strSQL & " GROUP BY 売上テーブル.支店コード "
>  strSQL = strSQL & " PIVOT Right([売上計上日],2);"
>
>  QD.SQL = strSQL
>  QD.Close
>  
>  MsgBox "クロス集計クエリ作成終了"
>
>End Sub
>
>
>上記をコピーし、標準モジュールに貼り付け実行させた後
>クエリ「Q_Cross」が出来る事を確認してみて下さい。
>
>
これで実行してみました。
支店は全部ちゃんと表示されました。
休日でデータのない日以外クロス集計で表示されるようにでてきました。
この状態でよろしいでしょうか?

また自分でもわからないなりにVBAを解読してみたのですが

どういった仕様になっているのか、よければ教えてください。

【11734】Re:データのないフィールドの表示
回答  小僧  - 10/7/14(水) 8:35 -

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

> ほかの仕事に追われなかなか手がつけられず返信できませんでした。
> 申し訳ありません・・・

いえいえ、MIT48 さんのペースで大丈夫ですよ^^


>支店は全部ちゃんと表示されました。

この段階ではまだ全支店を表示する処理をしていないので、
今回たまたま元データに
全支店のデータが存在していたのかもしれませんね。


>休日でデータのない日以外クロス集計で表示されるようにでてきました。
>この状態でよろしいでしょうか?

はい、問題ないです。
次にデータのない日を表示する処理を追加します。

クロス集計クエリの列見出しを固定するには
「IN」句を使います。
年月によって31日の処理やうるう年の処理がある為、
こちらも可変にしてあげます。

Sub MakeCrossQuery2()
Dim strSQL As String
Dim strIn As String
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim QD As DAO.QueryDef
Dim MyDate As Date
Dim i As Long
  
  MyDate = #6/21/2010#
  'MyDate = CDate(Format(DMin("売上計上日", "売上テーブル"), "@@@@/@@/@@"))
  Set DB = CurrentDb
  
  'クエリ Q_Cross の存在チェック
  'なかった場合には作成
  'あった場合には使いまわし
  
  strSQL = " SELECT * FROM MsysObjects WHERE NAME ='Q_Cross'"
  
  Set RS = DB.OpenRecordset(strSQL, dbOpenSnapshot)
  If RS.EOF Then
    Set QD = DB.CreateQueryDef("Q_Cross")
  Else
    Set QD = DB.QueryDefs("Q_Cross")
  End If
  RS.Close
  
  'クロス集計クエリの作成
  
  strSQL = ""
  strSQL = strSQL & " TRANSFORM Count(売上テーブル.伝票番号) AS 伝票番号のカウント "
  strSQL = strSQL & " SELECT 売上テーブル.支店コード "
  strSQL = strSQL & " FROM 売上テーブル "
  strSQL = strSQL & " GROUP BY 売上テーブル.支店コード "
  strSQL = strSQL & " PIVOT Right([売上計上日],2) "

    'In句の作成
    '20日締めなので21日〜20日は固定
      
    Do Until Day(MyDate) = 20
      strIn = strIn & ", '" & Day(MyDate) & "'"
      MyDate = DateAdd("d", 1, MyDate)
    Loop

  strSQL = strSQL & "IN (" & Mid(strIn, 2) & ",20);"

  QD.SQL = strSQL
  QD.Close
  
  MsgBox "クロス集計クエリ作成終了"

End Sub

今回は2010年6月21日〜7月20日までの処理を想定して

> MyDate = #6/21/2010#

としておりますが、
ここの日付を変化させる事で31日が出現したり
2月の処理をプログラム上で操作する事ができます。

売上テーブルの最小の日付を
セットする様なコードでも良いかもしれませんね。

ここまで出来ましたら次は全支店を表示する処理です。


> また自分でもわからないなりにVBAを解読してみたのですが
> どういった仕様になっているのか、よければ教えてください。

解りづらい処理がありましたら
どの箇所をご提示して頂ければ
出来る限り回答させて頂きます。

【11739】Re:データのないフィールドの表示
発言  MIT48  - 10/7/17(土) 15:07 -

引用なし
パスワード
   ▼小僧 さん:

また時間が空いてしまってすみません・・・m(__)m


>>支店は全部ちゃんと表示されました。
>
>この段階ではまだ全支店を表示する処理をしていないので、
>今回たまたま元データに
>全支店のデータが存在していたのかもしれませんね。

集計前のデータ集計に問題があり、全データでていたみたいです


>クロス集計クエリの列見出しを固定するには
>「IN」句を使います。
>年月によって31日の処理やうるう年の処理がある為、
>こちらも可変にしてあげます。
>
>Sub MakeCrossQuery2()
>Dim strSQL As String
>Dim strIn As String
>Dim DB As DAO.Database
>Dim RS As DAO.Recordset
>Dim QD As DAO.QueryDef
>Dim MyDate As Date
>Dim i As Long
>  
>  MyDate = #6/21/2010#
>  'MyDate = CDate(Format(DMin("売上計上日", "売上テーブル"), "@@@@/@@/@@"))
>  Set DB = CurrentDb
>  
>  'クエリ Q_Cross の存在チェック
>  'なかった場合には作成
>  'あった場合には使いまわし
>  
>  strSQL = " SELECT * FROM MsysObjects WHERE NAME ='Q_Cross'"
>  
>  Set RS = DB.OpenRecordset(strSQL, dbOpenSnapshot)
>  If RS.EOF Then
>    Set QD = DB.CreateQueryDef("Q_Cross")
>  Else
>    Set QD = DB.QueryDefs("Q_Cross")
>  End If
>  RS.Close
>  
>  'クロス集計クエリの作成
>  
>  strSQL = ""
>  strSQL = strSQL & " TRANSFORM Count(売上テーブル.伝票番号) AS 伝票番号のカウント "
>  strSQL = strSQL & " SELECT 売上テーブル.支店コード "
>  strSQL = strSQL & " FROM 売上テーブル "
>  strSQL = strSQL & " GROUP BY 売上テーブル.支店コード "
>  strSQL = strSQL & " PIVOT Right([売上計上日],2) "
>
>    'In句の作成
>    '20日締めなので21日〜20日は固定
>      
>    Do Until Day(MyDate) = 20
>      strIn = strIn & ", '" & Day(MyDate) & "'"
>      MyDate = DateAdd("d", 1, MyDate)
>    Loop
>
>  strSQL = strSQL & "IN (" & Mid(strIn, 2) & ",20);"
>
>  QD.SQL = strSQL
>  QD.Close
>  
>  MsgBox "クロス集計クエリ作成終了"
>
>End Sub

これで走らせてみたところフィールドに2桁で表示される
10日〜31日はデータ表示されるのですが、1日〜9日は表示
されませんでした。

なので
strSQL = strSQL & " PIVOT Right([売上計上日],2) "

strSQL = strSQL & " PIVOT Val(Right([売上計上日],2))"
と変更してみたらうまくいきました。


>> また自分でもわからないなりにVBAを解読してみたのですが
>> どういった仕様になっているのか、よければ教えてください。
>
>解りづらい処理がありましたら
>どの箇所をご提示して頂ければ
>出来る限り回答させて頂きます。


ありがとうございます
さっそくなのですが
Do Until Day(MyDate) = 20
>      strIn = strIn & ", '" & Day(MyDate) & "'"
>      MyDate = DateAdd("d", 1, MyDate)
>    Loop
>
この部分が今回上記の問題にもなったと思うのですが・・・
真ん中の処理がどうなっているのかぜんぜんわからなかったです

3連休ですがよろしくお願いします。

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