Microsoft Access 掲示板

6,744 件中 1,601 から 1,640 までを表示しています。
1

その後、試しに 『DoCmd.Close acForm, Me.name』としたら閉じました。一体何だったのか・・・

1
りんご 2023/11/20 (月) 15:31:05 935bc@0e907

 文字数調整じゃなくて、テキストボックスの幅で調整しないの?

5

hatenaさん 有り難うございます。大変分かり易く、勉強になりました。データ形式は今後注意していきます。(
念押しも忘れずに)

4

#で囲めば日付型になると思ってました。

この辺はなかなか複雑なので、いろいろ試しているうちに理解できるようになるでしょう。
イミディエイトウィンドウで下記のように記述して、それぞれの行でEnterキーを押してみてください。

?TypeName(#2023/11/20#)

?TypeName("#" & "2023/11/20" & "#")

前者はDate、後者はStringになります。後者は最初の質問のコードの記述と同じことですね。

VBAの決まりとして、コード中で#で囲まれた部分はDate型とみなす、"で囲まれた部分は文字列とみなす、となってます。
"#" は " で囲まれている文字列です。
これは決まりなのでそうなっていると覚えておくしかないです。

一つ教えて頂きたいのですが変数でDate型にしたら IF式には#で囲まなくても自動的にそう認識されるのでしょうか?

Date型の変数に代入する場合、Date型以外の値、例えば文字列を代入する場合、日付と判断できるものはDate型に自動で変換してくれます。(「暗黙の型変換」といいます)
数値を代入すると日付シリアル値(記述日からの経過日数)と判断してDate型に変換します。

If文内の比較式で、型が違う値同士を比較すると、「暗黙の型変換」で型を揃えて比較しようとします。
ただ、「暗黙の型変換」がプログラマーの想定通りになるとは限らないので、できれば型を揃えて比較した方が確実です。

テキストボックスの書式に日付書式を設定していれば(例えば yyyy/mm/dd)、Date型の値が返りますが、
回答のコードは念のためにCDate関数でDate型に変換して、Date型の変数と比較しています。

If CDate(Me.[入力日付]) >= kaisi And CDate(Me.[入力日付]) <= owari Then
3

hatenaさん有り難うございました。そのコードで上手くいきました。データ形式は重要ですね。#で囲めば日付型になると思ってました。一つ教えて頂きたいのですが変数でDate型にしたら IF式には#で囲まなくても自動的にそう認識されるのでしょうか?(CDateが重要?)
すずやんさんも有り難うございました。確かにそうですね、習慣づけます。

6

セキュリティが発動してVBA実行がブロックされているようですね。

「セキュリティの警告」バーの「コンテンツの有効化」ボタンをクリックしてください。

5
ACCESS 2023/11/18 (土) 10:27:34 f5ab3@cfbdf

hatenaさま
記事をコピーさせていただき貼り付けを行いました。
画像をアップロードさせていただきました。
ご確認よろしくお願いいたします。画像1

4

ブログのページにおいてあるファイルをダウンロードしたのではなく、記事の通りに作成していったということでしょうか。

表示されないということですが、具体的にどのような状況でしょうか。
その状態のスクリーンショットをアップロードしてもらえますか。

アップロードは投稿欄の下のツールバーの「画像アップロード」ボタンのクリックすると可能です。

3
ACCESS 2023/11/17 (金) 18:30:32 f5ab3@cfbdf

すずやん様 hatena様
回答ありがとうございます。
動作環境はWin11になります。
Accessのバージョンは2021になります。
F_Calendarのダウンロードファイル名とはどこの部分でしょうか。知識不足で申し訳ありません。
hatena様がご提示いただいているスケジュール管理フォームになります。その1から順にその3までを手順通り行い問題なく動作もしていました。念のために最初から作り直しをしており3度同様の症状が出ました。その際に修正などは加えてはいませんが3度目には若干の表示項目を変更してみました。
モニタも4Kではなく普通のモニタになります
このような回答でよろしかったでしょうか。初心者のためしっかりとした回答になっているかわかりませんがご確認よろしくお願いいたします。

2
すずやん 2023/11/17 (金) 16:42:17

そういうときってありますよね。
とりあえず条件判断を簡単にすればいいと思います。
あと、変数内に希望の値が入っているかを確認するのも重要です。

記載のあるコードの場合、「kaisi」「owari」「Me.[入力日付] 」に本当に自分の想定している値が入っているか、を「Debug.Print」で確認してみてはどうでしょうか。

またIF文の条件を「And」でつなぐとややこしくなるので、まずは分けて記載するのが良いと思います。
うまくいけば、最終的にまとめてみてはどうでしょうか。

1
hatena 2023/11/17 (金) 16:34:54 修正

データ型を意識するようにしましょう。
日付の比較をしたいのなら、日付/時刻型(Date)にすべきです。
"#" & Me.[tx初期日付] & "#"は文字列(String)です。

Dim kaisi As Date, owari As Date, kaeri As Integer

    kaisi = Me.[tx初期日付]
    owari = Me.[tx最終日付]
    If CDate(Me.[入力日付]) >= kaisi And CDate(Me.[入力日付]) <= owari Then
       Exit Sub
    Else
       kaeri = MsgBox("入力日付が今期の範囲外ですが、編集続けます?", vbYesNo)
    End If

ちなみに、VBAコード内に直接日付を入力する場合は、# で囲むことで日付/時刻型となりますが、
"#"を前後につけたら文字列です。"で囲まれたものは文字列ですので。

a = #2023/11/17# '日付/時刻型
b = "#" & "2023/11/17" & "#" '文字列 
7

ラベルのままで行くなら、Caption を参照するようにしてください。

=[開始].[Caption]
=[終了].[Caption]

テキストボックスにしておけば Caption は必要ないです。

テキストボックスの既定のプロパティ(省略したときに採用されるプロパティ)はValueですので、省略したら下記と同じ意味になります。

=[開始].[Value]
=[終了].[Value]

ラベルには既定のプロパティがないので、参照するプロパティ(Caption)を省略できません。。

6
うさぎ 2023/11/17 (金) 15:22:53 >> 5
=DSum("金額","T_売上","売上日 Between #" & "2023/10/1" & "# And #" & "2023/10/31" & "#")

は想定した値がでてきます。

=[開始]
=[終了]

はエラーになります。
現在はコントロールボックスの更新後処理としてラベルに日付が入力されるようにしています。
ラベルではなくテキストボックスを利用すべきでしょうか。

6

全角スペースから半角スペースへの置換は問題なく行われています。
抽出条件:Like "" & [T_置換用テーブル].[置換前] & ""  です。
合計で7つフィールドを並べ、OR条件で同じ抽出条件を記述しています。

恐らく全角スペースと半角スペースが区別されず、抽出条件に引っかかってしまっています。
置換自体は問題なく行えるようになったので、「置換したのにまだレコードが残っていて気持ち悪い」くらいの問題です。

5

置換後も、スペースを含むレコードが抽出されてしまいます。これは仕方ないことなのでしょうか?

" "(半角スペース)に変換はできていますか。
また、「スペースを含むレコードが抽出されてしまいます」とは、どのような抽出条件を設定した時の話でしょうか。

4

型変換エラーは出なくなりました!ありがとうございます。

もう一点質問なのですが、T_置換用テーブルの中に、置換前" "(全角スペース)、置換後" "(半角スペース)があります。
置換後も、スペースを含むレコードが抽出されてしまいます。これは仕方ないことなのでしょうか?

6

可能です。
サブ用の方は、メインの新規IDが必要になりますので、そこはDMax関数で取得することになります。

3

Nz関数でNullを""に変換したらどうでしょう。

レコードの更新:Replace(Nz([T_出力].[住所1],""),[T_置換用テーブル].[置換前],[T_置換用テーブル].[置換後])

Nz 関数 - Microsoft サポート

5
hiroton 2023/11/17 (金) 10:44:21 38ef6@f966d

「対象のラベル」とはどのように作ったものですか?
普通のテキストボックスを指定すれば特に問題なく動作すると思いますが

たとえば、正しく入力されたと想定して日付を直接記述して試してください

=DSum("金額","T_売上","売上日 Between #" & "2023/10/1" & "# And #" & "2023/10/31" & "#")

は想定した値が表示されますか?

また、

=[開始]
=[終了]

は、それぞれ入力しようとした値を表示しますか?

4
うさぎ 2023/11/17 (金) 10:27:30 >> 3

可能ならテキストボックス内で計算の方法をとりたいです。
売上の基準日が変わる可能性もあるため同じフォーム内の対象のラベル([開始][終了])から日付を持ってきて計算するようにしたいのですが以下だとエラーになります。

=DSum("金額","T_売上","売上日 Between #" & [開始] & "# And #" & [終了] & "#")
3

その後データを細かくみていくと日付を変換させているフィールドで一部エラーがでており、それで集計できない状態と思ってます。その分をまず処理して様子みてみます。

2

コメントありがとうございます。大元テーブルの金額部(2ヶ所あり)は通貨型になっております。エラーでるクエリBのその部分の合計フィールドの書式設定されてなかったので通貨型にしましたが、やはりオーバーフローとなります。
クエリBの基であるクエリAの件数は150程でそれをグループ化(金額は合計)しているだけなのですが・・・クエリBから金額フィールドを削除しても同じです。集計(Σ)を外すとエラーでません。何かグループ化に問題あり?・・・

1
すずやん 2023/11/17 (金) 09:41:58

「オーバーフロー」と表示される場合は、大概変数に想定外の値を入れてしまった場合に発生すると思います。

ざっくりな予想で申し訳ないですが、記載内容からすると、参照する金額に今までにない桁数の金額が入ってきたのではないでしょうか。
金額とのことなので、もしテーブルの値、変数の値に「int」を使われている場合、「money」に変えることで解決するかもしれません。

1
すずやん 2023/11/17 (金) 09:37:16

取り急ぎ以下の内容を記載されるのが解決への早道になると思います。

・動作環境
・Accessの明確なバージョン
・F_Calendarのダウンロードファイル名

また一度、新規でプロジェクトを作成しF_Calendarのみを実装してみてはいかがでしょうか。それで動く場合は作成中のプロジェクトと比較して進められると思います。

余談ですが、F_Calendarはモニタ画面の広さを取得しているのですが、4Kなどのモニタで使用した場合うまく動かない場合があるようです。
ただ一度でも動いている場合は当てはまらないかもしれません。

5
マスオ 2023/11/17 (金) 08:55:09 ddfe5@f146b

hatenaさん丁寧な解説ありがとうございます。SQL、DAOで直接した事はなくチャレンジしてみたいと思いますが、因みに手始めに追加クエリをメイン用、サブ用を用意してクエリ実行でも可能でしょうか?(すみません)

2
Anko 2023/11/17 (金) 08:34:46 修正 7fdfc@46fae >> 1

それで試しましたが型変換エラーが起きました。
置換用のテーブル・T_出力のテーブルはいずれのフィールドも短いテキスト型です。

また、総レコード4件、住所1と住所2だけを横並びにしてOr条件で更新をかけてみたところ、
12件の型変換エラーが出ました。
住所1はあるが住所2はない(住所2がNull?)レコードが実行前に12件あったので
Nullを短いテキスト型に更新しようとしてるのでは?と考えています

1

それぞれのフィールドの同じように設定すればいいのでは。

ただし、抽出条件は1行ずつずらして設定します。(OR条件になる)
あるいは、抽出条件をなしにてしもいいでしょう。

3

Replace([T_出力].[氏名],"??","?")で解決しました。

2

ある程度分けてクエリを作成してメンテナンスしやすしたいので、別クエリで作成しようと考えています。

1
hiroton 2023/11/16 (木) 15:33:33 779ca@f966d

わざわざ後から更新クエリ走らせずに、StrConvしてるところでReplaceもしてしまえばいいんじゃない?

Replace 関数

4

下記はDAOを使って新規追加する場合のコード例です。
こちらの方が分かりやすいかもしれません。

Private Sub 追加_Click()
    Dim rs As DAO.Recordset, mainID As Long
    Set rs = CurrentDb.OpenRecordset("メインテーブル", dbOpenTable, dbAppendOnly)
    rs.AddNew
    rs!フィールド1 = Me.テキスト1
    rs!フィールド2 = Me.テキスト2
    mainID = rs!メインID
    rs.Update
    rs.Close

    Set rs = CurrentDb.OpenRecordset("サブテーブル", dbOpenTable, dbAppendOnly)    
    rs.AddNew
    rs!メインID = mainID
    rs!フィールド1 = Me.テキスト3
    rs!フィールド2 = Me.テキスト4
    mainID = rs!メインID
    rs.Update

    rs.AddNew
    rs!メインID = mainID
    rs!フィールド1 = Me.テキスト5
    rs!フィールド2 = Me.テキスト6
    mainID = rs!メインID
    rs.Update
    rs.Close

End Sub
3

可能です。
下記はVBAで追加クエリのSQLを実行する場合のコード例です。

Private Sub 追加_Click()
    Dim stSQL As String, mainID As Long
    
    'メインテーブルへの追加クエリのSQL
    stSQL = "INSERT INTO メインテーブル (フィールド1, フィールド2) " & _
            "VALUES ('" & Me.テキスト1 & "','" & Me.テキスト2 & "');"
    CurrentDb.Execute stSQL, dbFailOnError '追加クエリの実行
    
    mainID = DMax("メインID", "メインテーブル") '追加したレコードのメインID取得
    
    'サブテーブルへの追加クエリのSQL(1レコード目)
    stSQL = "INSERT INTO メインテーブル (メインID, フィールド1, フィールド2) " & _
            "VALUES (" & mainID & "'" & Me.テキスト3 & "','" & Me.テキスト4 & "');"
    CurrentDb.Execute stSQL, dbFailOnError '追加クエリの実行
    
    'サブテーブルへの追加クエリのSQL(2レコード目)
    stSQL = "INSERT INTO メインテーブル (メインID, フィールド1, フィールド2) " & _
            "VALUES (" & mainID & "'" & Me.テキスト5 & "','" & Me.テキスト6 & "');"
    CurrentDb.Execute stSQL, dbFailOnError '追加クエリの実行

End Sub

詳細が不明なので、テーブル名、フィールド名、コントロール名は適当ですので雰囲気だけつかんで、あとは状況に合わせて改修してください。

3
hiroton 2023/11/16 (木) 13:26:34 779ca@f966d

そのクエリをレコードソースにしたフォームを新たに作り、望みの表の見た目にしてメインのフォームにサブフォームとして設置したらそれっぽいと思います


仕様がよく分からないんでクエリの回答してますけど、フォーム上に2つの合計値が表示されればいいだけならテキストボックスで計算させてもいいんじゃないですかね?

DSUM 関数

=DSum("金額","売上テーブル","Format(売上日,'yyyymm')="&[年月指定]&" AND Day(売上日)<=15)
=DSum("金額","売上テーブル","Format(売上日,'yyyymm')="&[年月指定]&" AND Day(売上日)>15)

2
マスオ 2023/11/16 (木) 12:19:00 ddfe5@f146b

hatenaさん ありがとうございます。2段階でも全然OKなのですが、それはコマンドボタン1つで可能でしょうか?

2
うさぎ 2023/11/16 (木) 11:26:30 >> 1

ありがとうございます。
こちらのクエリの結果を年月を指定したフォーム上に表1のような形で表示させたいと考えているのですがどのように行えばよろしいのでしょうか。

1
hatena 2023/11/16 (木) 11:12:43 修正

メインに追加してから、サブに追加という2段階ではだめなんですか。

メインのIDがオートナンバー型でインクリメントなら、最大値が新規IDということになります。

6
TX 2023/11/16 (木) 08:29:22 ddfe5@f146b

hiroton様 回答ありがとうございました。なるほどです! 一旦条件分岐での補正フィールドを作りそれを参照させると大分すっきりしますね。IIFとSwitchを組み合わせることもできるのですね。論理的なアイデアは素晴らしいです。
同じ結果になるものは一つにまとめるといいですね。短時間でこんなすごいアイデアがでてくるのは、本当にすごいです。
ありがとうございました。

5
hiroton 2023/11/15 (水) 17:06:40 e2c8b@f966d

最終的にすべてDateSerial(y, m, d)の計算をしているので、DateSerialを主に置くとすっきりすると思います

必要な要素をまとめて式にすると、次のように表現できそうです

DateSerial([年],[月]-[減算補正]+[月補正],[実日])

「減算補正」はマイナス計算しかないので式自体マイナスにしていますが、「月補正」はプラスマイナスあるのでプラスで作成しておきます

それぞれの補正の計算は

減算補正:IIf([選択1のID]=9,[減算値],0)

月補正:IIf([選択1のID]=9, Switch([A]=0 And [B]>0, 1, [A]>0 And [B]=0, -1, True, 0), IIf([X]>[Y] Or [選択2のID]=1 Or [選択2のID]=5, 1, 0))

のような形で作れます
これを上の式に当てはめてもいいですし、そのまま別フィールドにしてもいいでしょう


「減算補正」は簡単ですが、「月補正」は複雑ですね。求め方はこれに限りません
例えば、最終結果(1,-1,0)のグループを作る形で

//Switch([1になる条件], 1, [-1になる条件], -1, True, 0)の形にする

月補正:Switch([選択1のID]=9 And [A]=0 And [B]>0 Or [選択1のID]<>9 And ([X]>[Y] Or [選択2のID]=1 Or [選択2のID]=5), 1, [選択1のID]=9 And [A]>0 And [B]=0, -1, True, 0)

のようにしてもいいと思います
関数のネストが減るメリットはあるものの、やりたいことを直感的に表現できているか?とはちょっと離れているかな?という印象です

Switch関数は条件が真(True)になったときの値を返す関数なので、条件にTrueを指定すれば、そこで必ず値を返すことになります。「それ以前の条件で真が無ければこの値を返す」という、IIf関数における「偽のとき」の値を設定できます


条件式では様々な比較演算子を使うことができます

//↓の部分について
IIf([X]>[Y],DateSerial([年],[月]+1,[実日]),IIf([選択2のID]=1,DateSerial([年],[月]+1,[実日]),IIf([選択2のID]=5,DateSerial([年],[月]+1,[実日]),DateSerial([年],[月],[実日]))))

IIf(
  [X]>[Y]
 ,DateSerial([年],[月]+1,[実日])      // ←同じ結果を求めている
 ,IIf(
    [選択2のID]=1
   ,DateSerial([年],[月]+1,[実日])    // ←同じ結果を求めている
   ,IIf(
      [選択2のID]=5
     ,DateSerial([年],[月]+1,[実日])  // ←同じ結果を求めている
     ,DateSerial([年],[月],[実日])
    )
  )
)

このようないずれかに当てはまれば真というのはOrで表現できます

IIf([X]>[Y] Or [選択2のID]=1 Or [選択2のID]=5,DateSerial([年],[月]+1,[実日]),DateSerial([年],[月],[実日]))

Or比較はAnd比較と同じくらい使うので覚えましょう


蛇足
こう複雑な計算が必要になると、なんかこう、元のテーブル構造が怪しそうですね