Microsoft Access 掲示板

views
4 フォロー
6,283 件中 3,321 から 3,360 までを表示しています。
7
hiroton 2021/08/23 (月) 09:54:19 f1def@f966d >> 2

例えば

開始日終了日単価
2021/08/01Null150
2021/08/052021/08/10120
2021/08/112021/08/19130
2021/08/20Null140

のようなデータの時、指定日=2021/08/15の場合

指定日付>=開始日 AND ISNULL(終了日)=FALSE で抽出

すると

開始日終了日単価
2021/08/052021/08/10120
2021/08/112021/08/19130

と、2レコードHITします

2レコード以上は範囲入力側の制御の時点で入れられない形にしています

これは、つまり、このようなレコードは存在しないということでしょうか?だとすると、終了日に値の存在が許されるレコードは1つだけという歪なテーブル構造なんでしょうか?

質問の解自体はhatenaさんの回答の通りでしょう。ただ、手順や処理時間で見た簡略化は見込めないと思います。この観点から言えば

これ以上簡単にできる方法は

ないです

しかしながら、データ構造の観点から言えば、「一時的に変わる時」のデータは単純に追加するだけで済むというメリットができ、データ管理面での単純化なら見込めます

さらに言えば、既に指摘している通り、なぜ最終的なデータ構造でテーブルを作らないのか?という話になります。データ構造が単純で、データの取得もシンプルです
単純=「簡単」とは限らないですが、テーブル構造からはわからない独自ルールを運用するよりはよほど「簡単」でしょう。

単価情報を入力する側が期間限定明け後のデータ入力(ここでは8/11~8/19)を意識しなくてもいい形にしたいというものです

本当の主題はこれですよね?
ならば、職人芸のようなテーブル構造・データ取得を考えるよりも単純に「期間限定明け後のデータ入力(ここでは8/11~8/19)を」自動化したいと考えるべきでしょう

6
mayu 2021/08/21 (土) 10:38:56 修正 ef559@a99f1 >> 5

( 続き )
 

q_fromto

d_fromd_to
2021/08/112021/08/12
2021/08/232021/08/23

 

q_highlow

d_fromd_tohighlow
2021/08/112021/08/122021/08/012021/08/05
2021/08/232021/08/232021/08/132021/08/20

 

q_union

d_fromd_to基準開始日補填行単価
2021/08/112021/08/122021/08/011150
2021/08/232021/08/232021/08/131100

 

q_result

指定開始日指定終了日基準開始日補填行単価
2021/08/012021/08/042021/08/010150
2021/08/052021/08/102021/08/050120
2021/08/112021/08/122021/08/011150
2021/08/132021/08/192021/08/130100
2021/08/202021/08/222021/08/200140
2021/08/232021/08/232021/08/131100
2021/08/242021/08/272021/08/24015
2021/08/282099/12/312021/08/28030
5
mayu 2021/08/21 (土) 10:38:13 修正 ef559@a99f1 >> 4

( 続き )

# 最初は SQLの一筆書きを投稿しようとしたところ
# 160行の記述が長すぎて投稿不可であったことと
# サブクエリのネストが深くて、記述が複雑怪奇になったため、
# 構造別にクエリを複数( 計7つ )作るという回答に切り替えました。

まぁ...個々の記述が短いと 最終結果が出るまでの工程も分かりやすいでしょう。
( クエリを作る順番も、掲載した順と同じになります )

  • SQL文
  • クエリ名
  • SQLの結果セット

 

q_base

開始日終了日単価
2021/08/012021/08/04150
2021/08/052021/08/10120
2021/08/202021/08/22140
2021/08/132021/08/19100
2021/08/242021/08/2715
2021/08/282099/12/3130

 

q_ymd

ymd
2021/8/1
2021/8/2
2021/8/3
 ( 省略)
2021/8/25
2021/8/26
2021/8/27

 

q_ymdlist

ymd
2021/8/11
2021/8/12
2021/8/23
4
mayu 2021/08/21 (土) 10:37:19 修正 ef559@a99f1


開始日     終了日     単価
2021/08/01   Null      150
2021/08/05   2021/08/10   120
2021/08/20   Null      140

このようなデータで日付を指定した際に
指定日付 2021/08/01 ~ 2021/08/04 基準開始日 2021/08/01  単価150  
指定日付 2021/08/05 ~ 2021/08/10 基準開始日 2021/08/05  単価120
指定日付 2021/08/11 ~ 2021/08/19 基準開始日 2021/08/01  単価150
指定日付 2021/08/20 ~          基準開始日 2021/08/20  単価140
と基準開始日と単価が返ってくるようにしたいのです

  
私個人は、hirotonさんやhatenaさんと同じく
ソリューションとしては 圧倒的に
{ テーブルデータの保有形式を変更 } >>> { トリッキーな SQL または VBA }
という見解です。

ただ Access の一般機能で「 実現可能 」な ご要望であることも事実ですから
実用性とパフォーマンスは度外視で、SQL( クエリ )のサンプル を載せておきます。
( ※ 今回の投稿はテーブル定義とデータ例のみ )

なお、( 何らかの )日付範囲の抽出条件を満たした後のデータが
」の3行であるとするなら

指定日付 」に該当するような パラメータなりリテラル値は
開始日フィールドに指定された可能性が高いと推測し、
私の回答( SQL )では、現状のテーブルデータに影響を与えない抽出条件として

    開始日 >= dateserial( year( date() ), month( date() ), 1 ) 

を指定しています。
  

■テーブル: 単価マスタ

CREATE TABLE 単価マスタ
(
      rid    counter  not null primary key
    , 開始日 datetime not null
    , 終了日 datetime
    , 単価   money    not null
);
rid開始日終了日単価
12021/08/01150
22021/08/052021/08/10120
32021/08/13100
42021/08/202021/08/22140
52021/08/2415
62021/08/2830

  
  
■テーブル: T_num  

CREATE TABLE T_num ( num int not null primary key );

( T_num テーブル の num には 0 ~ 9 までの数値を入力 )

num
0
1
2
3
4
5
6
7
8
9
2

有り難うございます!やりたいことが実現できました。大変助かりました。

追加の質問があります。
1つのボタンで、一覧に表示されている請求書を1件つづ、自動的にPDF保存を繰り返し行わせるには、どのように記述したら
よいでしょうか。
可能であれば、ご教示頂きたく、よろしくお願いいたします。

3
hatena 2021/08/20 (金) 18:37:41 修正

hirotonさんの提示したテーブルのような形にしない限りは、簡単にはならないと思います。

どのようなUIなのか不明なので、
フォーム上に「日付」と「単価」というテキストボックスがあると仮定すると、
下記のようなコードで期待する結果にはなります。

Private Sub 日付_AfterUpdate()
    Dim res
    
    res = DLookup("単価", "単価マスタ", "#" & Me.日付 & "# Between 開始日 AND 終了日")
    
    If IsNull(res) Then
        res = DMax("開始日", "単価マスタ", "#" & Me.日付 & "# >=開始日 AND 終了日 Is Null")
        If Not IsNull(res) Then
            Me.単価 = DLookup("単価", "単価マスタ", "#" & res & "#=開始日")
        End If
    Else
        Me.単価 = res
    End If    
End Sub

hirotonさんの提示したテーブルなら、下記の1行のコードで済みます。

Me.単価 = DLookup("単価", "単価マスタ", "#" & Me.日付 & "# Between 開始日 AND 終了日")
2
tetsusi 2021/08/20 (金) 17:56:57 b557c@0c0d2

2レコード以上は範囲入力側の制御の時点で入れられない形にしています
>(8/5~8/10 & 8/6~8/11のような複数で日付が被る形はありません)

あくまで終了日付が入るのは期間限定の臨時の時だけで基本的には開始日で単価を制御するようになっており、
単価情報を入力する側が期間限定明け後のデータ入力(ここでは8/11~8/19)を意識しなくてもいい形にしたいというものです

1
hiroton 2021/08/20 (金) 17:01:16 13d29@f966d

指定日付>=開始日 AND ISNULL(終了日)=FALSE で抽出後

これ、結果は一意じゃないですよね。2レコード以上HITしたらどうしてるんですか?

このようなデータで日付を指定した際に
指定日付 2021/08/01 ~ 2021/08/04 基準開始日 2021/08/01  単価150  
指定日付 2021/08/05 ~ 2021/08/10 基準開始日 2021/08/05  単価120
指定日付 2021/08/11 ~ 2021/08/19 基準開始日 2021/08/01  単価150
指定日付 2021/08/20 ~          基準開始日 2021/08/20  単価140
と基準開始日と単価が返ってくるようにしたいのです

このデータ形式でテーブルを作らないのは何故なんでしょう?

6
hiroton 2021/08/20 (金) 15:17:10 13d29@f966d

重複を許さないだけならすでに挙げた方法でいいですが、既定のメッセージじゃ使いにくいのはありますね。2つ目の方法でメッセージを出してキャンセルする(=条件分岐を入れない)ようにすればいいです

Private Sub 日付_BeforeUpdate(Cancel As Integer)
    If Not IsNull(DLookup("日付", "テーブル名", "日付=#" & Me.日付 & "#")) Then
        MsgBox "既に入力された日付です。異なる日付を入力してください"
        Cancel = True
    End If
End Sub
5
ワッフル 2021/08/20 (金) 14:36:23 be3da@318ee

返信がわかりづらかったので、
再投稿です。

(レスの引用の仕方が
いまいちよく把握できてません)

りんごさん、hirotonさん
お二人様

御指南ありがとうございます。
どちらもかなり難しそうなので、
しばらくお時間をください。

ちょっと研究してみようと思います。

>hirotonさん
>これはOKなら重複を許すということですか?

これは、自分で書きながら、
改めて考えると重複を一切許さない方がいいかな?
と思いました。重複のお知らせと
入力キャンセルのみのメッセージボックスが
開いた方がいいかもしれないと思いました。

こうした場合は、どうしたらよいでしょう?

4
ワッフル 2021/08/20 (金) 14:34:32 be3da@318ee

りんごさん、hirotonさん
お二人様

御指南ありがとうございます。
どちらもかなり難しそうなので、
しばらくお時間をください。

ちょっと研究してみようと思います。

>hirotonさん

これはOKなら重複を許すということですか?

これは、自分で書きながら、
改めて考えると重複を一切許さない方がいいかな?
と思いました。重複のお知らせと
入力キャンセルのみのメッセージボックスが
開いた方がいいかもしれないと思いました。

こうした場合は、どうしたらよいでしょう?

3
りんご 2021/08/20 (金) 00:52:28 c564b@0e907 >> 1

 ごめんなさい、こちらにミスがありました。『リンク親フィールド:日付ID、リンク子フィールド:日付ID』のつもりが、『リンク親フィールド:日付、リンク子フィールド:日付』となっていました。サブフォームで示した件は間違いです。

1

下記のような感じでどうでしょうか。

   DoCmd.OpenReport "請求書", acViewPreview, , "[請求書番号] = " & Me.請求書番号 & ""
   DoCmd.OutputTo acOutputReport, "請求書", acFormatPDF, _
                       "C:\PDFOutput\" & Me.請求書番号 & "_" & Me.会社名 & "_" & Me.会社コード & ".pdf"
2
みかん 2021/08/19 (木) 09:53:51 399d8@9128f >> 1

hiroton様

確かにそうですね。。。

xlApp.Application.PrintCommunication = True
xlBook.Application.ActiveWorkbook.Save

    xlBook.Close
    xlApp.Quit

アドバイスの通りに処理を入れ替えてみました。
結果は30秒ほどで処理が完了し、Excel側も希望通りの値に変更になっておりました。

本当にありがとうございました。

1
hiroton 2021/08/19 (木) 09:36:22 6e3e0@f966d
xlBook.Application.ActiveWorkbook.Save

    xlBook.Close
    xlApp.Quit

    xlApp.Application.PrintCommunication = True

閉じた後に設定の変更って効く(意味がある)んですかね?
あと、設定を有効にする前に保存しているから設定が保存されないのでは?
処理の順番を入れ替えたらどうでしょう?

xlApp.Application.PrintCommunication = True
xlBook.Application.ActiveWorkbook.Save

    xlBook.Close
    xlApp.Quit


ついでに、主体はExcel VBAの話なので、解決が難しいようならExcel VBAに強い質問サイトを探すといいと思います

2
hiroton 2021/08/19 (木) 09:05:32 6e3e0@f966d

例えば、2021/08/18というデーターが過去に
あったなら、カレンダーや手入力で2021/08/18と
入力できなくする方法はありますか?

インデックスを使用してテーブル フィールドの値の重複を防ぐ


既に入力された日付です。OK、NO
みたいな形

これはOKなら重複を許すということですか?
上記方法はデータベース的に重複を許さない形なので、これをやりたい場合は自前で制御を組む必要があります。更新前処理イベントで入力しようとした値がすでに登録されているかどうかチェックすればいいですね

Private Sub 日付_BeforeUpdate(Cancel As Integer)
    If Not IsNull(DLookup("日付", "テーブル名", "日付=#" & Me.日付 & "#")) Then
        If MsgBox("既に入力された日付です。登録してもいいですか?", vbOKCancel) = vbCancel Then
            Cancel = True
        End If
    End If
End Sub
1
りんご 2021/08/18 (水) 22:26:39 c564b@0e907

フォームの日付のテキストボックスに

まずは、状況確認ですが、もしかしてこんな感じですか?
あと、どのテキストボックスがイメージに近いでしょうか?

親テーブル:日付ID,日付
子テーブル: 主キー,日付ID,その他
メインフォーム連結クエリ:日付ID,日付
サブフォーム連結クエリ:主キー,日付ID,日付,その他

フォームヘッダー
 日付テキストボックス(非連結):
詳細
日付ID:(新規)
日付 :
フォームフッダー
    📋サブフォーム
      サブフォームヘッダー
      日付テキストボックス(非連結):
      サブフォーム詳細

主キー日付ID日付その他フィールド
112021/08/18ほにゃらら
(新規)

            

主キー日付ID日付その他フィールド
112021/08/18ほにゃらら
(新規)2021/08/18

            

主キー日付ID日付その他フィールド
112021/08/18ほにゃらら
22021/08/18
(新規)

            

主キー日付ID日付その他フィールド
112021/08/18ほにゃらら
22021/08/18
(新規)2021/08/18

            

主キー日付ID日付その他フィールド
112021/08/18ほにゃらら
22021/08/18
(新規)2021/08/18

                                            親テーブル

主キー日付ID日付その他フィールド日付ID日付備考
112021/08/18ほにゃらら12021/08/18
22021/08/1822021/08/18
3
(新規)(新規)
1

いろいろな見解があると思いますが、
私は非連結フォームはほぼ使いません。
よってDAOからレコード操作もほとんど使いません。

 Access標準機能のクエリを使う、これは、やってはいけない事なのでしょうか?

どこにそのような情報があったか知りませんが、
クエリを使わないなら、Accessで開発する意味はないと思います。

7
nokonoko 2021/08/17 (火) 16:42:46 4ced3@54883

皆様ご回答ありがとうございます。
”上”と相談して、64bit版のofficeのPCで再確認したところ、
32bitのofficeで作成したaccdeは開けず、accdbは開けました。
64bitのofficeでaccdbからaccdeを作成すると、accdeは開けました。

ということで、大体解決しそうです。(あとは先方のpcで開けるか確認します)
ありがとうございました。

6
りんご 2021/08/17 (火) 13:04:44 c564b@0e907

上と相談してみます。
 32bit,64bit問題、私には懐かしいフレーズです。家庭用PCを慌てて確保した思い出が蘇りました。一般消費者から見れば、少なくとも5年前の話です。上と相談がうまいこといきますように、ファイトです。

5
hiroton 2021/08/17 (火) 12:01:42 0cfce@f966d

不具合解決にエラーメッセージは大事です。追記されているようなのでそれっぽい内容で検索してみました

ACCDEファイルが32Bit版と64Bit版で共有できない : Access(FeedSoftさん)

検索の仕方を変えればmicrosoftのドキュメントにも同様の内容を見つけられますね

(追記 相手側に渡しているのはaccdeファイルです。64bitでaccdeファイルを作ればよいという情報も見ましたが、そういうことなのでしょうか)

そういうことでしょう

4
hideki 2021/08/17 (火) 11:36:23 49c85@96514

回答ありがとうございました。
hatena様の見解を参考にさせていただきます。

3

経験上、8人ぐらいなら、連結でもそんなに重くならないと思います。

新規データの入力フォームなら、「データ入力用」プロパティを「はい」にしておけば全レコードを読みに行くこともないので。

非連結で入力フォームを作成したのは、作動が重くならないとNETで見つけたからです。

たまに、そのような話も見かけますが、実際、非連結でのコードはそんなに簡単ではないし、そんなにメリットはないと思います。

共有時の非連結フォームに関する私の見解は下記の質問にも回答してますので、参考にしてください。

デフォルトの楽観的排他制御 Microsoft Access 掲示板 - zawazawa

2
hideki 2021/08/17 (火) 10:42:47 49c85@96514

回答ありがとうございます。
非連結で入力フォームを作成したのは、作動が重くならないとNETで見つけたからです。
連結でも、非連結でも、作動は、関係ないのでしょうか?
環境としては、ネットワークドライブで、ACCESSを8人で共有して利用しています。

1

このようなコードで、入力フォームを作成しました。
同様のフォームが、残り7個あります。

この入力フォームが連結フォームで連結したテーブルを更新するのが目的なら、そもそもADOもDAOも必要ありません。
というかVBAコード自体必要ありません。

VBAでテーブル更新しているということは、非連結フォームで設計しているのでしょうか。
だとしたら、非連結にしている目的はなんでしょう。

検索しても見つからないのは、Accessにおいてそのようなことする必然性がほぼないからです。

4
nokonoko 2021/08/17 (火) 10:29:00 4ced3@54883

ありがとうございます。
該当ファイルはカレンダーコントロールは使っていないようですが、類似した何かを使っているのでしょうかね。

最終的には相手先と同じバージョンにして開発するのが確実な方法だと思います。

それが一番ですか。上と相談してみます。ありがとうございました。

3

フォームかレポートにカレンダーコントロールとかのActiveXコントロールを使っていませんか。

最終的には相手先と同じバージョンにして開発するのが確実な方法だと思います。

2
nokonoko 2021/08/17 (火) 10:09:11 4ced3@54883

hatena様
ご回答ありがとうございます。参照のページ、拝読いたしました。内容は理解できたと思います。

今回問題になっているファイルに、Declareを使っていないと思うのです。
Accessクラスオブジェクトと、標準モジュールのところで、検索しましたがヒットしません。
また、APIのような機能を使ってプログラムをした覚えもありません。(そもそも理解していません)

accessの理解が低くて大変申し訳ありませんが、Declare文とはもっと違うところに書かれているのでしょうか。

3
りんご 2021/08/16 (月) 23:30:42 c564b@0e907 >> 2

抽出条件に1と入力というのは、主キーで抽出するということでしょうか。
YES!
品目で抽出するとうまく抽出されません…
テーブル2の品目フィールドをクエリの行に追加するのはどうですか?
表示チェックを外して、抽出条件のところだけ、それを活用する感じで。

2
アオダイ 2021/08/16 (月) 23:01:38 d1e06@27a26

ご回答ありがとうございます。

抽出条件に1と入力というのは、主キーで抽出するということでしょうか。

主キーで「1」や「2」と抽出すると、ちゃんとそれに該当するレコードが表示されます。

品目で抽出するとうまく抽出されません…

1

通常は32bitOfficeで作成したデータベースファイルを64bitOfficeで使用可能です。

ただし、ActiveXコントロールを使っていたりすると使用できません。
ActiveXは使わないようにする必要があります。

また、VBAでWindowsAPIを使っている場合は、API宣言を質問のリンク先の方法で修正する必要があります。
API宣言の修正方法は下記の方がより詳しいです。

WindowsAPI をOffice64bit版または32bit版のVBAで使うには | hatena chips

4
hiroton 2021/08/16 (月) 11:53:52 15305@f966d

わざわざメインーサブにフォームを分けなければいいんじゃない?
フォームの挿入前処理イベントでMe.日付ID = 1とでもすれば登録だけならできるよ

3
ワッフル 2021/08/15 (日) 18:24:37 be3da@318ee

返信の機能がよく分からず、
見えづらい投稿となってすみません。

以後もっとわかりやすく投稿したいと思います。

2
ワッフル 2021/08/15 (日) 18:23:30 be3da@318ee

ご返答をありがとうございます。

>メインフォームとサブフォームのレコードソースのそれぞれのテーブルの関係は、一対多の関係でしょうか。

>だとしたら、原理的に無理です。一側のレコードがないと多側のレコードは入力できません。
>リレーショナルデータベースの制限です。

無理でしたか。残念です。

>現状のメインフォームとサブフォームのレコードソースのそれぞれのテーブルのフィールド構成はどうなってますか。

>テーブル設計、あるいはメイン/サブフォーム形式が適切でない可能性があります。

詳しく記載していただき、誠にありがとうございます。

例えば、サブフォームにしていたものを、
ボタンでフォームを開くといった形にしようかな?と思います。

またご質問することがあるかと存じますが、
その時もよろしくお願い致します。

1

フォームに、日付と日付IDと備考欄があります。
サブフォームとは、日付IDで連動しています。

フォーム(メインフォーム)上にサブフォームコントロールを配置して、
それの「リンク親フィールド」「リンク子フィールド」プロパティを 日付ID に設定しているという状況でしょうか。

フォーム(メインフォーム)の日付ID はオートナンバー型のフィールドでしょうか。

サブフォームにデーターを入力すると同時に、
フォームの日付IDを自動で決定して、サブフォームとフォームを
日付IDで連動できませんか?

フォーム(メインフォーム)は未入力、つまり新規レコードの状態で、
サブフォームの方でデータを入力したいということでしょうか。

メインフォームとサブフォームのレコードソースのそれぞれのテーブルの関係は、一対多の関係でしょうか。

だとしたら、原理的に無理です。一側のレコードがないと多側のレコードは入力できません。リレーショナルデータベースの制限です。

現状のメインフォームとサブフォームのレコードソースのそれぞれのテーブルのフィールド構成はどうなってますか。

テーブル設計、あるいはメイン/サブフォーム形式が適切でない可能性があります。

1
りんご 2021/08/15 (日) 01:33:55 c564b@0e907

ググッただけですが、連結値と表示値を理解するとあります。抽出条件に1と入力するとどうなりますか?

ルックアップ フィールドを作成または削除する - Microsoft サポート
この記事では、ルックアップ フィールド (列) を作成し、ルックアップ フィールド プロパティを変更し、ルックアップ フィールドを削除する方法について学習します。
Microsoft

2
MASA2021 2021/08/10 (火) 22:36:36 d4978@eaf17

解決いたしました。
ありがとうございました。

1

引数で対象コントロールを渡せはいいでしょう。

標準モジュール

Public Sub initButton(btn as Control)
    Const Chrsize = 10
    With btn
        .FontSize = Chrsize
        .BackColor = RGB(191, 191, 191)
    End With
End Sub

フォームモジュール

Private Sub Form_Load()
    Call Module1.initButton(Me.button1)
    Me.button1.Caption = "01_Japanese"
End Sub
1

「宛名ラベルを押した瞬間」の宛名ラベルとは具体的になんのことでしょうか。