Microsoft Access 掲示板

views
4 フォロー
5,901 件中 361 から 400 までを表示しています。
1

※前回hatenaさんに忠告いただいたソースコードの掲載の仕方 やり方がわからないです。。。。;;

前回の回答のリンク先にていねいに説明してありますので、もう一度よく読んで、質問文を編集してください。

あの説明で分からないとなると、このような掲示板でのやりとりで解決に至るのは困難だと思います。

あと、フォームの構成がどうなっているかの説明も追加してください。
下記の点についての情報を追記してください。

メインフォーム、サブフォームのレコードソースの設定
リンクフィールドの設定
テーブルのフィールド構成、フィールドのデータ型、主キー設定

5

人間には同じように見えても、コンピューター(Access)からはまったく別物です。

例えば、
人間が見てテキストボックスが空の場合に、入力を即したい場合がよくあります。
未入力(Null)、""(空文字列)、スペースのみ、は人間からみたらすべて同じですが、
コンピューターからはすべてまったく別物に見えます。
未入力(Null)、スペースのみを""に変換して、テキストボックスが空だとコンピューターにもわかるようにしてあげる必要があります。

コンピューターは人間のように融通がききませんので。

最近はAIで結構融通が利くようになってきていますが、VBAは一昔前から進歩してませんからね。

4
すずやん 2024/02/16 (金) 17:39:32 >> 3

Nullと空欄は厳密には違います。

よって「= ""」で「""」と判断できるのは「""」だけで、NULLだと同じではないと判断されます(確かそうだったはず)

プログラマーは過去に確実に動いたコードを多用する傾向があるので、おそらく前担当者がその方法に慣れていたのではないでしょうか。

3
驚天動地!前任者失踪丸 2024/02/16 (金) 17:19:28 23e8e@44ebd >> 2

正にIf文で使われております。
質問の為当該箇所のみ抜粋して記述しました。

Nullも長さのない文字列も同じように見えるのに、わざわざ変換をかけていることに
どのようなメリットがあるのか、識者の皆様の考えをお聞かせいただきたいです。

2

そのコード単体で1行になることはないはずです。エラーになりますので。

たぶん、下記のような感じで使われているのではないでしょうか。

If Trim(Nz([テキストボックスの名前], "")) = "" Then
   'テキストボックスが未入力(Null)だったりスペースのみの場合の処理
Else
   'テキストボックスにスペース以外の文字が入力されいるときの処理
End If
5

haetnaさんの回答にある Mid(strFilter, 6) は何かで見た事がありますがやっと意味がわかりました。”はカウントせずに半角スペースはカウントに入るのですね。因みにMe.FilterOn = (strFilter <> "")の右辺はTrueと同じ意味になるのでしょうか?

(strFilter <> "")は、strFilter が ""(空文字列) でなければ True、""(空文字列) なら False になります。
下記のコードと同義になります。

If strFilter <> "" Then
    Me.FilterOn = True
Else
    Me.FilterOn = False
End If

5行のコードが1行で済むのでついつい使ってしまいますが、コードの意味のつかみやすさからいけば、5行で書いた方がいいですね。

hirotonさんの回答にある Private Sub setFilter() 'フィルタをかける処理 ですが変数自体にコード記述が出来るのですね? フォーム上のイベントにはそれは出来ないのでVBA画面に直接記述したらいいのでしょうか?

VBAに直接記述します。
Private Sub setFilter() は変数ではなくプロシージャです。
Subプロシージャ、Functionプロシージャについて調べてください。

#1 のhirotonさんの最初のコードの 'フィルタをかける処理 の部分を #2 の私のコードに置き換えればOKです。

1
すずやん 2024/02/16 (金) 16:37:43

2重に処理しているようですね。
まず「Nz」でテキストボックスに文字列が入っていればそれを、入っていない場合は「""」(空欄)を「Trim」に渡しています。
「Trim」では渡された文字列に前後の空白があればこれを削除します。「""」が渡された場合は何もしません。

ただ最後の「 = ""」は謎ですね。
そんな使い方できるんだろうか。

21

IDが増えても(レコード件数が増えても)、コードを修正する必要はないです。
全レコードを対象にチェックします。

実際にやってみてうまくいかなかったのでしょうか。
もし、そうなら、どのようなデータでどのような結果になったのか、どこが想定と違うのか説明してください。

4
COCO 2024/02/16 (金) 15:22:21 ddfe5@469dd

hirotonさん haetnaさん ありがとうございました。
haetnaさんの回答にある Mid(strFilter, 6) は何かで見た事がありますがやっと意味がわかりました。”はカウントせずに半角スペースはカウントに入るのですね。因みにMe.FilterOn = (strFilter <> "")の右辺はTrueと同じ意味になるのでしょうか?
hirotonさんの回答にある Private Sub setFilter() 'フィルタをかける処理 ですが変数自体にコード記述が出来るのですね? フォーム上のイベントにはそれは出来ないのでVBA画面に直接記述したらいいのでしょうか?
知識不足で、すみません。

20

hatenaさま 参考にさせていただき、今テーブルに入力しているID19から22のチェックができるようになりました。今後チェックするIDが34まで増え、19から22、その途中27から34も一度にチェックしたい時などには、どのように書き換えればよろしいでしょうか?DMin("ID", "T1")やDMax("ID", "T1")を19や34にして複数同じなものを作る以外のスマートの方法をお願いできますか?

5
hiroton 2024/02/16 (金) 12:19:28 b198c@8db65

マスタとトランザクションをキーワードに調べてみることをオススメします

「単価」は一般的にその商品に付随するデータ、ユニークなキーによって決定される単一のデータなので「集計データ」と見なすことはまずないでしょう

実際にどのように管理すべきか?は検討の余地の有るところですが今回の質問とは関係の薄い話ですね

4
りんご 2024/02/16 (金) 12:18:08 935bc@0e907 >> 3

新しい質問で、テーブル構造を提示した上で、意見募集するのはどうでしょう?

3

横からすいません。
集計データをテーブルに格納しない場合、例えば商品Aの単価が100円から200円に変わった場合などに合計金額などに不都合が発生するように感じたのですが、問題ないのでしょうか?

2
苦節1年 2024/02/16 (金) 11:44:14 ca7cf@20718

ありがとうございます!
そもそも論が聞けてスッキリしました。
頭をリフレッシュして違う方向からトライしてみようと思います。
なんとか抜け出せて本当に助かりました。

1

「総合計」のような集計データはテーブルには格納しないというのが、データベース設計の基本です。
必要に応じて、その都度計算するような設計にします。
集計クエリ、演算コントロールでのSum,Count関数、DSum,DCount関数など、状況に応じて適切な方法を使いわけましょう。

例えば、今回の質問のフォームでは演算コントロールでその都度、計算してますよね。

どうしてもテーブルに格納するというのなら、サブフォームの更新後処理で代入するということになります。
が、更新や入力か必ずそのフォームから行われるのならいいですが、そうとは限らない場合もあるでしょうし、更新後処理がエラーなどでうまくいかないなど、など、、、その集計が正しいという保証がないので、通常はそのようなことはせずに、その都度計算します。

4
すずやん 2024/02/16 (金) 09:14:07

こちら解決できました。ありがとうございます。

原因は下記リンク先にある通り「CDO.Message」は「SMTP over SSL (ポート465)」の SMTP認証方式を使う為、「TLS/STARTTLS (ポート587)」のSMTP認証方式には対応していないとのことでした。

https://mofuken.blogspot.com/2014/07/windows-cdomessage.html

ただ現在使用しているメールサーバーが「SMTP over SSL (ポート465)」に対応していない為、ちょっと修正する必要がありそうです。
当面はSSLをFALSにしてポートを25で使うことで回避することにしました。

3
すずやん 2024/02/16 (金) 09:09:52 >> 2

ご返信ありがとうございます。
原因は教え得頂いたリンクの2番目と同じでした。
>VBAからCDOを使用してメール送信時にサーバ接続エラー

こちら無事解決しました。

2

ちょっと調べましたがこれと同じでしょうか?

CDOでMicrosoft365メールが使えなくなったので調べてみた #mail - Qiita
https://qiita.com/mindwood/items/c5b4475db6ddbfdb0372
中小企業情シス稼業 : VBAからCDOを使用してメール送信時にサーバ接続エラー
https://www.1josys.com/archives/38212996.html

1
すずやん 2024/02/15 (木) 16:04:06

なぜか文字コードを記載すると、表記が文字化けしてしまいましたので、別途記載します。
コード中の「文字コード」という部分には「ISO-2022-JP」と記載しています。

3
hiroton 2024/02/15 (木) 14:14:06 48bf2@f966d

具体的なフィルタ文字列生成部分に関しては、複数の組み合わせに対して、「直前の出力があった場合だけ"AND"を出力する」ということになりますが、これを毎回チェックするのはめんどくさいので、「出力があればとりあえず" AND "を付ける」「最後に無駄な" AND "を消す」ようにします


これ入力してたらコード例をhatenaさんが投稿されたのでコードはそちらを参考に


このように、「似たような処理」を「共通になるような処理」に落とし込めればすっきりしたコード記述ができるようになります

19

数値が重複する場合があるんですね。
はい、あります。その場合もあると お伝えしなければいけなかったのですね。すみません。

伝達事項の少ない中で、ご返信本当にありがとうございます。
上記を参考に作成してみます。また壁に当たるかと思いますが、ご指導お願いいたします

18

質問不成立です

すみません。

2

未選択(Null)の場合は条件なしということですね。

条件式変数に選択してあれば条件を追加していくという方法でいいでしょう。

フィールド名は適当、データ型は数値型の場合ですので、実際のものに合わせて修正してください。

Dim strFilter As String

If Me.[cb1].Value <> "" Then
    strFilter = strFilter & " AND フィールド1=" & Me.[cb1].Value
End If
If Me.[cb2].Value <> "" Then
    strFilter = strFilter & " AND フィールド2=" & Me.[cb2].Value
End If
If Me.[cb3].Value <> "" Then
    strFilter = strFilter & " AND フィールド3=" & Me.[cb3].Value
End If

strFilter = Mid(strFilter, 6) '先頭の" AND "を削除
Me.Filter = strFilter
Me.FilterOn = (strFilter <> "")
1
hiroton 2024/02/15 (木) 13:56:16 48bf2@f966d

プログラミングの基本ですが、共通の処理は関数にまとめるものです

なので、「共通になるような処理を考えてそれを呼び出すようにする」とスマートです

ACCESSのフィルター処理は結構テンプレート的な感じで、ここでも同じような回答を何度かしてますが、自作のプロシージャを作ってそれを呼び出すようにすると良いです

例えば、以下のようにsetFilterプロシージャを作成し、各コンボボックスの更新後処理でそれを呼び出すようにします

Private Sub cb1_AfterUpdate()
    setFilter
End Sub

Private Sub cb2_AfterUpdate()
    setFilter
End Sub

Private Sub cb3_AfterUpdate()
    setFilter
End Sub

Private Sub setFilter()
'フィルタをかける処理
End Sub

各イベントが、プロシージャの呼び出ししかしないのであれば、そのプロシージャを関数にして、ユーザー定義関数の呼び出しの形にするとコードはもっとすっきりしますね

モジュール

Private Function setFilter()
'フィルタをかける処理
End Sub

各コントロールの更新後処理プロパティ

=setFilter()
17
りんご 2024/02/15 (木) 13:54:16 935bc@0e907 >> 15

「ここからアウト」だよってことを調べたいのです。

 その後、どうしたいの?最終的に、やっている事がレッドカードになる場合、質問不成立です。

16

数値が重複する場合があるんですね。
だとすると、前回の私の回答では、うまくいかない場合があるので、ちょっと修正します。

数値が同じ場合、IDの並び順が不定になるので、IDの並び順も指定しておく必要がありました。

Public Sub SequenceCheck3()
    Dim MinId As Long, MaxID As Long
    MinId = DMin("ID", "T1"): MaxID = DMax("ID", "T1")
    
    Dim StepNum As Long, SeqNum As Long, stOrder As String
    If DLookup("数値", "T1", "ID=" & MinId) < DLookup("数値", "T1", "ID=" & MaxID) Then
        StepNum = 1   '昇順
        SeqNum = MinId
        stOrder = "昇順"
    Else
        StepNum = -1  '降順
        SeqNum = MaxID
        stOrder = "降順"
    End If

    CurrentDb.Execute "UPDATE T1 SET 連番チェック = Null WHERE Not 連番チェック Is Null;"
    
    Dim sSQL As String
    sSQL = "SELECT * FROM T1 ORDER BY 数値, ID"
    If stOrder = "降順" Then sSQL = sSQL & " DESC"
    
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset(sSQL)
    Do Until rs.EOF
        If rs!ID <> SeqNum Then
            rs.Edit
            rs!連番チェック = stOrder & "×"
            rs.Update
        End If
        SeqNum = SeqNum + StepNum
        rs.MoveNext
    Loop

    rs.Close
    Set rs = Nothing
End Sub
15
ぽん 2024/02/15 (木) 12:45:28 53dda@1925b

ご指摘ありがとうございました。21がアウトですよ の説明です
最大値の22、最小値の19は合っているけれど、数値で並べ替えると22の次が21番が連番じゃなくて
20番になっているからアウトですよ ってことを調べたかったんです。
前回ご指摘をいただいたように4件しか表示していなかったのですみません。 
件数を増やしました。再度ご教授お願い致します。
ID 数値
19 1.91
20 1.90
21 1.89
22 1.86
23  1.88
24  1.81
25  1.81
とデータがあったとき数値を昇順に並び替える
25 1.81
24  1.81
22  1.86
23  1.88
21  1.89
20  1.90
19  1.91
ID 25から24までは連番 21から19番も連番だけど 24から22は連番にならないから「ここからアウト」だよ
ってことを調べたいのです。お願いいたします

5

住所データを一回csvなりExcelなりのアウトプットしなきゃいけないのですか???

Googleマイマップにインポートできるファイル形式がAccessに対応していないのでそうなります。

私としては 抽出した住所データをACCESSのユーザーフォームから
ワンクリックでグーグルマップに反映されるものを作りたいと思っているのですけど、、、
可能でしょうか?

可能ですけど、簡単ではないです。

まずは、手作業でご希望のマップを作成できるようになってください。
できたら、その作業を自動化することを考えます。
csvへのエクスポートはVBAで簡単にできます。
その先は、ブラウザの自動操作になりますので、難易度は一気に高くなります。

今なら、VBAでやる場合、seleniumを使うことになると思います。「VBA selenium」でWEB検索して研究してみてください。

あるいは、RPA(PC操作自動化ツール)を使うとかになります。

4
rinrin 2024/02/14 (水) 20:33:51 b4dc9@c7f00

この回答に関する質問なのですが、、、
住所データを一回csvなりExcelなりのアウトプットしなきゃいけないのですか???

私としては 抽出した住所データをACCESSのユーザーフォームから
ワンクリックでグーグルマップに反映されるものを作りたいと思っているのですけど、、、
可能でしょうか?

3
rinrin 2024/02/14 (水) 20:11:48 b4dc9@c7f00

早急な回答ありがとうございます。。。^^
いつもいつもすごいですね^^神です^^

今 会社でACCESSを使って 当該内容の抽出プログラムを構築してます^^
あたしのスキルではまだまだ時間もかかると思います。。。;;
でも
hatenaさんが応援してくれるから、、、明日からもがんばりますね^^
P.S.当該ACCESSなのですが、、、次から次へと壁にぶつかってしまう現状です。。。;;
決して脱線したり、、、あきらめたりするわけではないので、、、
今後も当該プログラムに付随した質問をさせていただくことご了承ください。。。^^

完成を待ってたら お礼がずーっと先になってしまうので
ありがとうございました

1
hiroton 2024/02/14 (水) 17:35:35 da393@f966d

結構な頻度で使うことがありますが、今まで使っていて使えなくなったことはないですね
下手に外部機能を組み込むよりはACCESSで完結してる機能のほうが信頼できると思っています

買い切りのシステム販売とかに組み入れるのはNG(使えなくなった時にサポートできないから)

どういう理由で「使えなく」なるのを想定してるんでしょうか?
「案件」のものであれば動作環境がきちんと提示されるものなので「使えなくなった時にサポートできない」のは当然のものだと思いますが

14
hiroton 2024/02/14 (水) 13:12:15 da393@f966d

そういえばこれ、数値を昇順にすると

ID数値上位とチェック下位とチェック
221.8622→20:連番ではない
201.8822→20:連番ではない20→21:連番
211.8920→21:連番21→19:連番ではない
191.9121→19:連番ではない

クエリの昇順だと20と21が逆になっているので、今のままなら21がアウトですよ。と分かるようにしたいです。

全部アウトじゃない?
少なくとも、「21がアウトですよ」はどういう基準でそれがアウトなのか意味が分かりませんね

>> 11のhirotonの回答はその辺適当です

13

テーブルデータを入力または更新したタイミングですね。つまり連番が崩れる可能性のあるタイミングでチェックするということです。

12
名前なし 2024/02/14 (水) 12:24:44 53dda@1925b

お二人ともありがとうございました。
初心者の私には、即答できないので実際に この構文を加工させていただいて実行してみたいと思います。
ちなみに hatenaさんの場合も、フォームの読み込み時イベントでよろしいですか?

11
hiroton 2024/02/14 (水) 09:36:22 da393@f966d

フォームに読み込んで表示するとして、フォームの読み込み時イベントに[イベント プロシージャ]を設定して、

Private Sub Form_Load()
    Dim lastRecord As Long
    Dim lastID As Double
    Dim sortSign As Long
        
    lastID = Me!ID
    DoCmd.GoToRecord , , acLast
    lastRecord = Me.CurrentRecord
    sortSign = IIf(lastID < Me!ID, 1, -1)
    
    DoCmd.GoToRecord , Me.Name, acFirst
    lastID = Me!ID - sortSign
    Me!フィールド = Null
    Do
        DoCmd.GoToRecord , Me.Name, acNext
        Me!フィールド = IIf(Me!ID * sortSign > lastID * sortSign, Null, "×")
        lastID = Me!ID
    Loop Until Me.CurrentRecord = lastRecord
End Sub
1

リンクテーブルを削除して、再度リンクしなおすことになるのでは。

そもそも、フィールド名が変更されるというのはデータベース的にはNGなので、その都度リンクして、そのデータを正規形に変換して、テーブルに追記するという処理になると思います。

2

Google マイマップ を使えば可能です。

作成の仕方は下記リンクを参考に。

地図を作成する、開く - パソコン - マイマップ ヘルプ

住所データのインポートは下記のリンクを参考に。
インポートできるファイルはCSVやXLSXなどがありますので、Acccessの住所データをテキスト(CSV)かエクセルへエクスポートすれば簡単に作成できます。

地図上の対象物をファイルからインポートする - パソコン - マイマップ ヘルプ

1
rinrin 2024/02/13 (火) 21:05:31 b4dc9@c7f00

住所の一覧表はExcelじゃないと無理なんですか???::

7
rinrin 2024/02/13 (火) 20:19:11 b4dc9@c7f00

できました^^ あっさりできました^^
ほんとうにありがとうございました
これからもご指導何卒宜しくお願いします^^

10

テーブルに表示させたいなら、テーブルに表示用のフィールドを追加することになります。

例えば、 連番チェック という名前のテキスト型のフィールドを追加したとして、下記のような感じです。

Public Sub SequenceCheck2()
    Dim MinId As Long, MaxID As Long
    MinId = DMin("ID", "T1"): MaxID = DMax("ID", "T1")
    
    Dim StepNum As Long, SeqNum As Long, stOrder As String
    If DLookup("数値", "T1", "ID=" & MinId) < DLookup("数値", "T1", "ID=" & MaxID) Then
        StepNum = 1   '昇順
        SeqNum = MinId
        stOrder = "昇順"
    Else
        StepNum = -1  '降順
        SeqNum = MaxID
        stOrder = "降順"
    End If

    CurrentDb.Execute "UPDATE T1 SET 連番チェック = Null WHERE Not 連番チェック Is Null;"
    
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("SELECT * FROM T1 ORDER BY 数値;")
    Do Until rs.EOF
        If rs!ID <> SeqNum Then
            rs.Edit
            rs!連番チェック = stOrder & "×"
            rs.Update
        End If
        SeqNum = SeqNum + StepNum
        rs.MoveNext
    Loop

    rs.Close
    Set rs = Nothing
End Sub