Access VBA質問箱 IV

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

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


17 / 500 ページ ←次へ | 前へ→

【12987】Re:消費税計算について
発言  まるこ  - 16/4/14(木) 13:59 -

引用なし
パスワード
   かるびの様

お礼が遅れて申し訳ありません
悪戦苦闘していますが、なかなかうまくいかない上にクエリを作ったり消したりしているうちにファイルが膨張してしまいました涙
なので今は現実的にはまだ以前のようにエクセルを直していますが、うまくできましたらまた報告させていただきます
途中報告のみにて失礼させていただきます。
ありがとうございました
・ツリー全体表示

【12986】Re:Accessで市販の定型帳票に印刷可能?
お礼  tako  - 16/4/7(木) 22:44 -

引用なし
パスワード
   ▼かるびの さん:
いつものことながら早い回答ありがとうございました。早速請求書の発行でトライしてみます。ありがとうございました。
・ツリー全体表示

【12985】Re:Accessで市販の定型帳票に印刷可能?
回答  かるびの  - 16/4/7(木) 10:41 -

引用なし
パスワード
    可能です。
 ただし、市販の帳票あるいは既存の定型帳票に合わせたレポートを作成する必要があります。

 つまり、市販の帳票あるいは既存の定型帳票を物差しで測り、
印字箇所ごとに逐一、印字位置や幅・高さなどを測って、
それを元にレポートを作成します。

 これだけでは、実際に印刷するとずれたりすることがあるので、
何度もテストをして、レポートのテキストボックスの位置や幅・高さの微調整を行って、
完成させます。

 プリンタを変えたり、プリンタのドライバを変えたりした場合、それらの位置がずれる可能性があります。
 そうなった場合、再テストをする必要があります。その結果、微調整が必要になることがあります。
・ツリー全体表示

【12984】Accessで市販の定型帳票に印刷可能?
質問  tako  - 16/4/7(木) 7:23 -

引用なし
パスワード
   Access2016を使用しています。
1つ1つレポートを作成して印刷していますが、直接市販の帳票あるいは既存の定型帳票に合わせて印刷することができますか?
・ツリー全体表示

【12983】Re:AccessにはWordのような
お礼  たけお  - 16/3/31(木) 23:11 -

引用なし
パスワード
   ▼かるびの さん:
ご回答ありがとうございました。業務用のメニューフォームでしたので装飾性豊かに作成しようとしました。Accessにそのような機能がないのであればWordArtで作成したものを、画像の貼り付けのような形で処理するしかありませんね。そうします。ご回答ありがとうございました。


wordで作成した
・ツリー全体表示

【12982】Re:特定のテーブルのみ別に保存するVBA
お礼  あな  - 16/3/30(水) 8:34 -

引用なし
パスワード
   かるびのさま
ご指摘ありがとうございました。全くそのとおりですね。
しかし断れない感じなので、コピーの方法を参考に
させていただきます。ありがとうございました。
・ツリー全体表示

【12981】Re:AccessにはWordのような
回答  かるびの  - 16/3/29(火) 20:19 -

引用なし
パスワード
    ワードはほぼ使ったことがなく、「ワードアート」なるものがどんなものかわからない上、
当方のアクセスは2003のため、最新のアクセスがどんな機能を持っているかもわかりませんが、
アクセスでは、凝った装飾的表現はできないはずですので、
「ワードアート」なるものの類似の機能はないと思います。


 ちなみに、私が持っている中上級向けのアクセスの解説本には、
装飾的表現はやめろと書いてありました。
 仕事で使うのであれば、結局はシンプルなのが最も使いやすい、という理由です。
・ツリー全体表示

【12980】Re:特定のテーブルのみ別に保存するVBA
回答  かるびの  - 16/3/29(火) 20:07 -

引用なし
パスワード
   >そのテーブルだけ
>別のAccessデータファイルとして保存するVBAをつくって、
>フォームのボタンで自動化したいのです。

 あまり感心しませんね。

 データベースにおける基本的ルールとして、一事実一箇所というルールがあります。
 これは、データの格納は一箇所だけにしろということです。
例えば、顧客管理のデータベースにおいて、顧客の住所は、一箇所だけに格納しろということです。
言い換えれば、顧客のデータをコピーしてあちこちのテーブルに持つようなことはしてはいけない
ということです。
 データをコピーしてあちこちのテーブルに格納しておくと、
最新のデータ、あるいは正しいデータがどれなのかわからなくなってしまうからです。

 御希望のことは、一事実一箇所の原則に反することになってしまうので、避けるべきです。


 では、どうするかですが、
テーブルをコピーして新ファイルに保存するのではなく、
新ファイルでは、当該テーブルをリンクテーブルとして使うべきです。
 例えば、例えば、元データが格納されている甲.accdbファイルがあり、
このうちのAテーブルとBテーブルだけを使って、乙.accdbファイルで処理をしたいという場合、
乙.accdbファイルにおいては、AテーブルとBテーブルをリンクテーブルとすべきだということです。


 リンクテーブルとすることが不可能である場合であって初めて、
テーブルのコピーを考えることになります。

 その場合は、予め、甲.accdbファイルのAテーブルとBテーブルと同じ構造のテーブルを、
乙.accdbファイルに作っておきます。
なお、乙.accdbファイルにおいては、それぞれaテーブルとbテーブルだとします。

 そして、フォームに設けたコマンドボタンのクリックイベントで、
aテーブルの全レコード削除、
bテーブルの全レコード削除、
Aテーブルからaテーブルへの追加クエリ、
Bテーブルからbテーブルへの追加クエリ
を順次実行します。
・ツリー全体表示

【12979】特定のテーブルのみ別に保存するVBA
質問  あな  - 16/3/29(火) 10:30 -

引用なし
パスワード
   すみませんが教えてください。
AccessVBAでつくったデータベースを仕事で使ってます。
たくさんのテーブルがあるのですが、別の部署でそのうちの
2個だけ必要で、容量を小さくしたいのでそのテーブルだけ
別のAccessデータファイルとして保存するVBAをつくって、
フォームのボタンで自動化したいのです。(毎日行うので)
よろしくお願いします。
・ツリー全体表示

【12978】AccessにはWordのような
質問  たけお  - 16/3/27(日) 22:17 -

引用なし
パスワード
   Accessのメニューフォームの作成にあたって、標題をワードのワードアートで作成するような人を引き付けるような文字で表現したいのですが、Accessにはこのような機能はないのでしょうか?
ワードで作成したものをコピー貼り付けするしか方法はありませんか?
・ツリー全体表示

【12977】Re:Valueプロパテイについて
発言  かるびの  - 16/3/25(金) 11:03 -

引用なし
パスワード
    複数値フィールドですか。

 複数値フィールドは、アクセス2007以降の新機能であり、
当方のアクセスは2003のため、複数値フィールドは使えず、使ったこともありません。
 そのため、次のページを紹介するくらいしかできません。

ht tps://support.office.com/ja-jp/article/%E8%A4%87%E6%95%B0%E5%80%A4%E3
%82%92%E6%8C%81%E3%81%A4%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3
%81%AE%E6%A6%82%E8%A6%81-7c2fd644-3771-48e4-b6dc-6de9bebbec31


 ただ、複数値フィールドの評判はあまりよくないようです。

 以前、どこかの掲示板で、識者が「複数値フィールドは扱いづらそうだ」という意見を述べていたのを記憶しています。

 また、複数値フィールドを使いたくなるような場面で、複数値フィールドを使わずに実現する方法は存在します。
 2003以前では、この方法をとるべきものとされていました。
 そのため、下手に複数値フィールドを使うと、
どのテーブルとどのテーブルを使って、どのようなクエリを作るか
ということが見通しづらくなってしまいます。

 こうしたことから、複数値フィールドは敬遠されているのではないかと思います。


 なお、複数値フィールドを使わない場合にどうすべきかについて触れておきます。


 社員が取得した資格を管理したいということですから、
作るべきテーブルは、次のようなものになると思います。

テーブル名:T社員
フィールド:
社員ID オートナンバー型(主キー)
社員名 テキスト型(又は短いテキスト)

テーブル名:T資格
フィールド:
資格ID オートナンバー型(主キー)
資格名 テキスト型

テーブル名:T保有資格
フィールド:
保有ID オートナンバー型(主キー)
社員ID 長整数型
資格ID 長整数型

 なお、T社員とT資格は多対多結合となります。
そのため、結合テーブルが必要になりますが、T保有資格がそれに該ります。

 そして、レコードの表示は、メイン/サブ形式のフォームを使って行うことになると思います。
 すなわち、メインフォームに社員名などを表示させ、
サブフォームには当該社員が持っている資格を表示させます。
 下記のような感じです。

┌────────────┐
│    ┌────┐  │
│社員名 │田中  │  │
│    └────┘  │ 
│            │
│┌─────────┐ │ 
││資格名      │ │
││英検3級     │ │
││珠算2級     │ │ 
││簿記3級     │ │
│└─────────┘ │
└────────────┘

 このイメージは、メインフォームを単票フォーム、サブフォームをデータシート又は帳票フォーム
としたものですが、メインフォームを帳票フォームにしたり、データシートにすることもできます。


 クロス集計クエリを作りたいとのことですが、こんな感じでしょうか。

    英検3級 珠算2級 簿記3級 
 山田     1     0     0
 田中     1     1     1
 中村     0     0     0
 村木     0     1     1

 このようなクロス集計クエリは、上記に示したテーブルから作ることができます。
 具体的には、
 まず、上記の3テーブルを結合させたクエリを作ります。このクエリの名前を仮に「Q結合」だとします。
 次に、Q結合をベースにして、クロス集計クエリを作ります。
集計方法は、「カウント」を選びます。
 
 こうすれば、複数値フィールドを使わなくても、上記のようなクロス集計クエリを作れます。
・ツリー全体表示

【12976】Valueプロパテイについて
質問  柚木健夫  - 16/3/24(木) 14:43 -

引用なし
パスワード
   現状資格リストを見て社員がそれぞれ取得した資格を入力しています。
単一のルックアップフイールドはリストから一つの値しか保存できませんが、
複数の値を持つフイールドには複数の値を選択して保存できる。
つまり一つのフイールドにいくつもの資格名を登録できる。
また複数の値を持つフイールドの内容を表示するにはValueプロパテイーを使用してクロス集計クエリを作成し、列表示に資格名、行表示に社員名、値欄に資格数を表示できる。ということを知りました。
肝心要の複数の値を持つことができるフイールドの作り方、Valueプロパテイーの作成の仕方がわかりません。
ご教示ください。よろしくお願いします。
・ツリー全体表示

【12975】Re:消費税計算について
回答  かるびの  - 16/3/24(木) 12:20 -

引用なし
パスワード
    この問題って、よく聞きますね。
 
 例えば、税抜きで93円の物と税抜きで189円の物をそれぞれ1個ずつ買うとします。
 端数は四捨五入されるものとします。

 2つの物を一緒にレジを通すと、支払う合計は
(93+189)×1.08=304.56
となり、端数を四捨五入すると、支払額は305円となります。

 他方、2つの物を別々にレジを通すと、支払額は、
93×1.08=100.44
189×1.08=204.12
となるので、
100+204=304円
となります。

 2つの物を一緒にしてレジを通すか、別々にしてレジを通すかによって支払額に1円の差が出てくるわけです。
 価格によっては、上例とは逆に、一緒にレジを通した方が安くなるという場合も出てきます。

 これを利用して、日々の買い物において節約に励んでいる主婦がいるという話を聞いたことがあります。


 で、質問に立ち返ります。
 上例で見たとおり、
端数処理後に合計するか(上例では別々にレジを通す場合)、
合計後端数処理をするか(上例では一緒にレジを通す場合)
により最終的な額が変わってくることがあります。
 これは、避けることができません。

 結局、出したい価格が、端数処理後に合計なのか、合計後端数処理なのかに合わせて計算するしかありません。


 本件において、税抜き価格を合計した後に税率をかけて、税込み合計額をアクセスで計算したいなら、

SELECT 注文CD, Sum(金額) AS 合計
FROM クエリA
GROUP BY 注文CD

というクエリBを作り、さらに

SELECT 注文CD, 合計額 * 1.08 AS 税込合計
FROM クエリB
GROUP BY 注文CD

というクエリCを作るということになります。
 そして、出力先のエクセルに合うよう、
クエリCをうまく組み合わせて、さらにクエリをうまく組み立てる
ということになります。
・ツリー全体表示

【12974】消費税計算について
質問  まるこ  - 16/3/23(水) 15:10 -

引用なし
パスワード
   何度もすみません
よろしくお願いします

注文CD カテゴリCD 品名 本体金額
A001  1    鉛筆 300
A001  2    下敷 471
A001  1    筆箱 378
A001  3    硯  459
A001  6    花  643
というデータがあるとします

◎A業者からの請求書(注文CD毎に発行されます):
注文CDA001分:
合計 2251
税額 180
税込合計 2431

請求金額を下記のようなクエリ処理した後一覧表にして、エクセルにエクスポート後オラクルだか何だかの支払用システムにインポートするという処理をしています

SELECT クエリA.注文CD, クエリA.カテゴリCD, Sum(Int([金額]*1.08)) AS 金額1
FROM クエリA
GROUP BY クエリA.注文CD, クエリA.カテゴリCD
ORDER BY クエリA.注文CD;

◎B当方の処理クエリAの結果   
注文CD カテゴリCD  金額1
A001  1     732
A001  2     508
A001  3     495
A001  6     694
税込合計 2429

と注文CD単位で税込合計に2円の差が出てしまいます
今現在はエクセルにエクスポートされた時点で手で直しています(例えば上記のような場合だと694を696にする等)が、この差を業者側に合わせた金額で出力されるようにしたくていろいろ錯誤しています

やってみたこと:

◎Aと◎Bの差額を算出し、クエリに表示させ、足し算する

例)の場合だと4行になる為最終合計で×4足されてしまうのでダメ

やってみたこと2:

エクセルにエクスポートする際、サマリされた合計金額を業者請求書に合わせた金額で出力させる

エクセルに計算式が入っている為無理

とここまでは考えられたのですが・・・
またバンザイになってしまいました
ご教示よろしくお願い申し上げます
・ツリー全体表示

【12973】Re:Dlookupの値がクリップボードに送られ...
お礼  つかさ  - 16/3/16(水) 20:55 -

引用なし
パスワード
   ありがとうございます!
複雑なコードの間にいれていたため、どうやら受注フォームを選択していなく、レポートを開いた瞬間にこのコードを読み込む順番になっていたのが原因でした!
・ツリー全体表示

【12971】Re:Dlookupの値がクリップボードに送られ...
回答  亀マスター  - 16/3/15(火) 1:15 -

引用なし
パスワード
   使い方は合っていると思います。
単純に思い浮かぶのは、DLookupのWHERE句がおかしいとかで、
DLookupの返り値がNullになっている(該当するものがない)
ということでしょうか。
MsgBox DLookup(...,...,...)とかで、DLookupの返り値が
望むものになっているか確認しては?
もしかして、「combo納品先名」が列数2以上のコンボボックスで、
ドロップダウンで表示されているものとValueプロパティで
取得出来るものが違うのでは?
・ツリー全体表示

【12970】Dlookupの値がクリップボードに送られない
質問  つかさ  - 16/3/14(月) 23:35 -

引用なし
パスワード
   初めまして。

早速ですが、質問させてください。。困っています。

ボタンを押すと、クリップボードに変数の文字列が送られ、そのあとコピーで任意の場所に張り付けられるというシステムを作っております。
実際に作ったVBAのコードは以下になります。


Set Clip = CreateObject( _
   "new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  
  Clip.GetFromClipboard
  Clip.SetText "○○○○" & DLookup("納品先ID", "納品先台帳", "納品先名 ='" & combo納品先名 & "'")
  Clip.PutInClipboard
  
  Set Clip = Nothing


ながったらしいコードになってしまったのは、microsoft forms 2.0 object libraryを直接FM20.DLLを選んだとしても参照できなかったためです。
あきらめかけましたが、なんとか上記のコードを書いてある場所を見つけコピーしたところ正常に動きました。

しかし、上記のコードですと

"○○○○" までしかクリップボードにコピーできず、肝心な「納品先ID」がコピーできません。Dlookupのやり方は間違っていないようで、ちょっとでも変えると全くクリップボードにコピーできなくなります。

Str(Dlookup…) で行いましたが、やはり何もクリップボードに送られませんでした。

やはりDlookupが間違っているのでしょうか。
どなたかわかる方教えて頂ければ幸いです。。。
・ツリー全体表示

【12969】Re:Docmd.RunSQLだと問題ないのにDataba...
発言  亀マスター  - 16/3/14(月) 20:20 -

引用なし
パスワード
   自己レスになりますが、部分的に対応方法ができました。

DLookupでデータを取得している部分で、以下のように
変更すると、更新後のデータを正常に取得出来ました。

Dim DB As DAO.Database
Dim RS as Recordset

'↓↓DLookupの代替↓↓
Set DB = CurrentDb
Set RS = DB.OpenRecordset("SELECT フィールド名 FROM テーブル名 WHERE WHERE句")
変数 = RS!フィールド名
RS.Close
'↑↑DLookupの代替↑↑

正直、これが良くてDLookupがダメな理由はよくわかりませんが、
CurrentDBあたりでキャッシュを無視してファイルのデータを読みに
いっているのかとか思ってます。他の環境でも同じようにうまくいく
保証はないのですが。

また、Me.Requeryがうまくいかないのは解決していません。
似たような発想でForm.RecordSourceをセットし直してみたり
したのですが、やっぱり古いデータのまま…。
・ツリー全体表示

【12968】Re:Docmd.RunSQLだと問題ないのにDataba...
お礼  亀マスター  - 16/3/11(金) 0:23 -

引用なし
パスワード
   かるびの さん 回答ありがとうございます。

>>しかし、そうすると、Me.Requeryをしたにも拘わらず、更新前の
>>ままになってしまいます。また、別のフォームで、
>>Me.RequeryのところにDLookupを使っているものがあるのですが、
>>そちらでも、更新前のデータしか得られません。
>
> これらの事象は、非同期実行よる典型例だと思います。
> 事態が逆転してしまっていますね。実に妙なことだと思います。困惑するばかりです。

そうなんですよね。
非同期実行を防ぐ意味もあってDatabase.Executeを使っているのに、どうして…。

> トランザクション処理は、トランザクション中は、追加クエリなどの結果をメモリにとどめておき、
>CommitTrans により一気にファイルに書き込むものです。
> 全く根拠はありませんが、ここが非同期実行になっているのかもしれません。
> だとすると、トランザクションをやめることが、一つの対策となるかもしれません。

クエリの複数連続実行をしている部分があるので、エラーが起こった場合の
ロールバック処理をするために、トランザクションは使いたいところなんですよね…。

>>WSP.CommitTrans dbForceOSFlush
>>
>>DBEngine.Idle dbRefreshCache 
>
> dbForceOSFlush 定数とか、Idle メソッドとかがあるのは、全く知りませんでした。
> また、これらを使ったこともありません。
> なので、これらの効果や使用の是非については、私には何とも言えません。

上記の原因が、メモリ上の命令をデータベースファイルに反映するのが遅れていたり
読み取りにいった時にキャッシュから読んでしまっている可能性を考え、
OSのキャッシュを即座にデータベースファイルへ反映させるためのオプションと、
AccessのReadキャッシュを即座に最新のものにするためのもの(というつもり)です。
ただ、これを付けても付けなくても、結果は変わってないのですが…。

概ね5秒ほど待ってから読みにいくと正常にデータを拾えることから、
Me.RequeryやDLookupの段階でReadキャッシュを読んでしまっている可能性が
高いと思っているのですが(キャッシュの更新間隔がデフォルト設定だと
5秒程度らしいので)、だったらDBEngine.Idle dbRefreshCacheで解決するはず
なのに…。

トランザクションははずしたくないので、どうしてもダメならSleepで5秒待機を
させることにします。ユーザー側からしたら待ち時間が目に付くかもしれませんが、
データ不整合によるエラーを起こすよりはマシなので。

引き続き、参考になることがあればお願いします。
・ツリー全体表示

【12967】Re:Docmd.RunSQLだと問題ないのにDataba...
回答  かるびの  - 16/3/10(木) 10:47 -

引用なし
パスワード
   >実は元々DoCmd.RunSQLを使っており、その際は問題なかったのですが、
>複数のSQLを連続して使う際にあまりよくないと聞いたもので、
>Database.Executeを使うパターンに切り替えたのです。

 同期・非同期の問題ですね。

 RunSQL メソッドは非同期実行、Execute メソッドは同期実行と言われています。

 非同期実行というのは、例えば、RunSQL メソッドで追加クエリを実行した場合、
追加クエリが完了しないうちに、VBAにおける次行のコードが実行されてしまうものです。
 このため、次行実行時には、まだレコードが追加されていないということが起こり得ます。
 そうなると、あると思っていたレコードがテーブルにはないということになってしまうので、
思っていた結果にならないということになってしまいます。

 これに対し、同期実行であれは、追加クエリが完了しないうちは、
VBAにおける次行のコードが実行されません。
 そのため、上記のような問題は生じません。
 
 こうしたことから、追加クエリの実行は、Execute メソッドを使った方がいいと言われています。


>しかし、そうすると、Me.Requeryをしたにも拘わらず、更新前の
>ままになってしまいます。また、別のフォームで、
>Me.RequeryのところにDLookupを使っているものがあるのですが、
>そちらでも、更新前のデータしか得られません。

 これらの事象は、非同期実行よる典型例だと思います。
 事態が逆転してしまっていますね。実に妙なことだと思います。困惑するばかりです。


 その原因はわかりません。

 ただ、強いて言えば、トランザクション処理にあるのかなと思います。

 トランザクション処理は、トランザクション中は、追加クエリなどの結果をメモリにとどめておき、
CommitTrans により一気にファイルに書き込むものです。
 全く根拠はありませんが、ここが非同期実行になっているのかもしれません。
 だとすると、トランザクションをやめることが、一つの対策となるかもしれません。
 

>WSP.CommitTrans dbForceOSFlush
>
>DBEngine.Idle dbRefreshCache 

 dbForceOSFlush 定数とか、Idle メソッドとかがあるのは、全く知りませんでした。
 また、これらを使ったこともありません。
 なので、これらの効果や使用の是非については、私には何とも言えません。
・ツリー全体表示

17 / 500 ページ ←次へ | 前へ→
ページ:  ┃  記事番号:
1078200
(SS)C-BOARD v3.8 is Free