Microsoft Access 掲示板

views
4 フォロー
6,283 件中 161 から 200 までを表示しています。
4
茶々 2024/07/30 (火) 16:05:04 35169@b17c5

accessの項目は以下です。

ID    →オートナンバー
支払日  →複製したい場合とExcelから張り付ける場合がある
支払種別 →複製したい場合とExcelから張り付ける場合がある
支払先名 →複製したい場合とExcelから張り付ける場合がある
部門名  →空白でok 
施設名   →複製したい場合とExcelから張り付ける場合がある
金額     →Excelから貼り付け
支払方法 →複製
該当月  →複製したい場合とExcelから張り付ける場合がある
備考   複製したい場合とExcelから張り付ける場合がある

・ひとつひとつ入力していく場合
このいくつかの項目の内容が同じ場合は、1行複写するボタンを使って、変わるものだけを入力しています(金額とか施設名とか)

Excelから貼り付けたい時
・各担当者が入力したデータを貼り付ける場合、元のExcelには支払方法・該当月がないので、
accessのコピー元に入れてコピーするか、またはExcelの方に追加してから貼り付けています。

・そのほか、光熱費やネットでの購入品などはcsvでダウンロードしたものを、支払日・支払い方法・該当月はこちらでコピー元に入れてコピーし、金額はcsvから貼り付け、施設名は別の施設名一覧Excelから貼り付け、等にしています。

このような感じで、元のレコードを複写しておいて、ところどころを貼り付けたいのです。

施設名 支払方法 該当月 だけを入力したレコードを、貼り付け用に100行用意する(=100回ボタンを押す)をしているので、それが10回押せば100行用意出来たら、すごく楽だなぁ、と思ったのです。

3
hiroton 2024/07/29 (月) 18:00:12 bdecc@f966d >> 1

そういうことですね。ExcelとACCESS(データベース)はデータの持ち方が違うので、互いにデータをやり取りする場合は、データの形式を合わせるという作業が発生します

上記では「新規レコードを追加」で例にしましたが、テーブル上の操作では、既存レコードの見た目上2x2マスに、Excel上の2x2からコピーペーストもできますよ


ACCESS上の操作としてコピーペーストはできるとしましたが、問題の本質は、ACCESSで扱うために新たなデータを作りたいということでしょう

もう少し具体的には「新たなデータを作りたい」=「任意のレコード追加をしたい」ですね

さらに条件を挙げていくと、
「任意のレコード」=複数一括追加もしたい
「ID」->オートナンバーで取得
「日付と項目等」->既存レコードの複製=レコード追加前に一括で指定(準備)
「金額と備考欄等」->Excel上のデータ

と、現在手作業で行っていることをシステム(ExcelやAccess)に合わせて論理的に説明できるようになれば、あとはそれをシステム化するだけです(「Excel上のデータをどう指定するか」はもっと事細かに考える必要があります)

先にも上げましたが、データの形式を合わせるの部分をどれだけ正確に説明できるか?が問題です。具体的なシステム化部分はこの掲示板で多分それほど難しくない内容で回答が付くと思います


1行コピーして10行または20行複製

この前後も含めて理解に困るところですが、「10行コピーして10行」「20行コピーして20行」ではないんですかね?

1行が10行になるということは何十行ものExcelデータが何百何千のAccessデータになっているんでしょうか?

2

ありがとうございます。簡単ではないのですね。
Excelで作られたものが全く同じ形式ではないのと、オートナンバーの関係もあって、
例えば日付と項目等をレコード複製しておいて、金額と備考欄等をExcelから貼り付け、というふうにしています。
頻繁ではないですが、百回以上複製ボタンを押すことがあるので、まとめて出来たらなぁ~という淡い期待でした💦

1
hiroton 2024/07/29 (月) 16:46:37 bdecc@f966d

いろいろ複雑な要件が絡む問題ですが、

普通にExcelで複数行コピーしたものを、ACCESSのテーブルでレコードを選択状態(左端のレコードセレクタ部分をクリック)にして張り付ければ新規レコードの追加として全て張り付きますよ

3
しん 2024/07/28 (日) 10:08:38 051ad@9fff4

hiroton様
返信遅くなりまして申し訳ございません。

2
しん 2024/07/28 (日) 10:08:12 051ad@9fff4

hiroton様 回答ありがとうございました。
ファイル名は認識されていませんでした。
絶対パスなら認識されました。
回答ありがとうございました。

2
あん 2024/07/26 (金) 11:57:49 b41ab@001b1

hiroton様

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

教えていただいた「データベース構造の解析」で出来そうです。

Excelに落として検索していってみます。

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

1
hiroton 2024/07/26 (金) 11:00:44 09adb@f966d

Access データベースの構造について

データベース構造の解析

レポートで表示されますが、Excelにでもエクスポートすればテキスト検索できます

9
ダイリ 2024/07/25 (木) 19:42:34 d0802@1c608

いつも各種資料を見させて頂いている中、指導ポイントがスゴイ。
ここまで適格に指導されているホームページは他にはないと思います。

6

ご認識の通り正規化するど、T_履歴_機種、T_履歴_加工のテーブルも必要になりますね。
データの集計や検索などのデータ操作を効率よく行うには必須の設計になります。

T_履歴 と T_履歴_機種、T_履歴_加工 の関係は「一対多の関係」といいますが、このような場合、入力フォームの設計はAccessではメイン/サブフォーム形式のフォームを使用するのが一般的です。
検索すればサンプルが多数見つかりので、参照してみてください。

①T_入力という上記フィールド(受注№以外)を持つテーブルをレコードソースにした、F_入力というフォームで入力を行う(T_履歴には登録ボタンを押して、確定した情報しかレコードして残したくないため)

このようなことを実現するには、下記の2つの方法が考えられます。

T_履歴、T_履歴_機種、T_履歴_加工 と同じフィールド構成の一時テーブルを作成して、それをソースとするメイン/サブフォームを作成して、入力フォームとする。

あるいは、現状の入力フォームを非連結にして、登録ボタンでVBAで T_履歴、T_履歴_機種、T_履歴_加工 にデータ追記する。
コントロール名を規則的なものにしておけば、ループ処理でシンプルなコードで実現できると思います。

コントロール名(チェックボックス)が 「機種_1」「機種_2」「機種_3」・・「機種_26」として下記のような感じです。

Dim rs_履歴_機種 As DAO.Recordset
Set rs_履歴_機種 = CurrentDB.OpenRecordset("T_履歴_機種")

Dim i As Long
For i = 1 to 26
    If Me.Controls("機種_" & 1).Value = True Then
        rs_履歴_機種.AddNew
        rs_履歴_機種!機種ID = Me.受注№.Value
        rs_履歴_機種!機種ID = i
        rs_履歴_機種s.Update
    End If
Next

T_履歴_機種 に登録する部分のコードの考え方です。これを参考にコード作成してみてください。
ほかの部分も同様にできると思います。
登録する順番は先にメインテーブル(T_履歴)のほうからしてください。

5
hiroton 2024/07/25 (木) 11:09:23 6ac35@f966d

まず、目的をはっきりさせましょう。提示されなければ質問者以外にはわかりません
どのような作業(仕事)をするためのシステム(ツール・道具)を作りたいんでしょうか?

それとも、ACCESS(データベース)を学習すること自体が目的のサンプルシステムなんでしょうか?


>> 3にある①②③は手段ですね
目的(どのような結果が欲しいのか)が不明なので、どのような手法を勧めるべきかに至っていません。当然、具体的な手段の話にもなりません。どのようなテーブルを用意すべきか?も具体的な検討に至れません

4

画像1

正規化調べましたが、T_入力をどうしたらいいかわかりません。
ここからどのようにすればよいでしょうか。

3
NoName 2024/07/24 (水) 17:36:05 修正 f3f60@44ebd >> 2

機種マスタ

機種ID(主キー)機種名
1A
2B
3C
4D
26Z

こんな感じのマスターテーブルを作って、T_履歴には機種フィールドにマスタの機種IDをいれればいいのでしょうか?でもそれだと機種を複数選択できません。

今のT_履歴のテーブル構成は、詳細省いてますがこんな感じです。


履歴ID(オートナンバー)受注№(主キー・数値)担当者コード(数値)得意先コード(数値)受注日(日付)品名(短いテキスト)納期(日付)機種_A~Z(YesNo)加工_1~10(YesNo)特記事項_1~3(YesNo)包装_ゴム止め個数(数値)包装_ケース個数(数値)包装_紙帯個数(数値)

①T_入力という上記フィールド(受注№以外)を持つテーブルをレコードソースにした、F_入力というフォームで入力を行う(T_履歴には登録ボタンを押して、確定した情報しかレコードして残したくないため)
②F_入力の登録ボタンを押すと、T_入力の内容を追加クエリでT_履歴に追加(この際に受注№を取得)
③F_前回受注№入力というフォームのtxb_受注№(非連結)というテキストボックスに受注№を入力して反映ボタンを押すと、追加クエリでF_入力にその受注№のレコードを追加し、前回入力した内容がF_入力に反映された状態で入力を開始できる

以上のようなことをやりたいのです。
フィールドを横並びにしておけば、追加クエリとかが少なくて済むかなと思ってこのようなテーブルにしました。

きちんと正規化するとT_履歴_機種、T_履歴_加工とかのテーブルも作らないといけないですよね?

2

T_履歴というテーブルに、「機種_A」から「機種_Z」までの26種類のフィールドがあるとします。

発想がデータベース的ではないですね。
データベースではデータを横方向に展開する(フィールドが増える)ような設計はしません。
このような設計ではデータベースとして使い物になりません。

そのような設計にしたいのならエクセルで作成することをお勧めします。


提示されている情報だけではテーブルデータの全体像が分かりませんので、具体的にどのようなテーブル設計にすべきかは提示できません。
とりあえず、「テーブル 正規化」をキーワードにWEB検索してみて、データベースの基本を学習されることをお勧めします。

4

折り返しも考慮して3行以内ととうことですね。

等幅フォントなら、文字数から折り返しを計算できますので、可能だとは思います。
ただし、全角/半角の文字幅、ワードラップ、禁則処理なども考慮する必要があるので、簡単ではないですね。

プロポーショナルフォントだと文字毎に幅が異なるのでAPIが必要になるのでさらに難易度が高くなります。

不可能ではないと思いますが、わたし自身は必要性を感じないので、コードを提示することはしません。

レポートなら、テキストボックスの印刷時拡張機能で折り返しで行数に合わせて高さが拡張されるので、そこから折り返し後の行数を取得することは可能です。

蛇足

テキストデータを行数で分割するというのは、データベース的ではないと思います。
見た目の問題だと思うので。

私がするなら、1フィールド(1テキストボックス)に入力させて、必要に応じて、分割するという方法をとりますね。

1
NoName 2024/07/24 (水) 15:58:48 f3f60@44ebd

画像1

Excelで申し訳ありませんが、イメージです

3

回答ありがとうございます。
実装できたのですが、改行無しで2行や3行になった場合、4行目・5行目を入力することができてしまいます。

例えば、幅7㎝、高さ1.5cmのテキストボックスにフォントサイズ14だと、文字詰め無しのフォントで1行あたり14文字入力、スクロールなしで3行分表示できるのですが、20文字入力すると6文字分が2行目に行き、入力を進めていくと4行目、5行目にも入力出来てしまいます。

コード的に、改行("")の個数で判断してるためだと思いますが、解決方法はありますでしょうか。

1
hiroton 2024/07/24 (水) 09:00:50 0f429@f966d

ファイル名が正しくありません

なので、とりあえずファイル名が正しいのか(VBAが正しくファイルを認識できているのか)調べてみては?
また、Accessファイルを単純な場所において直接指定して実行できるのか確認してみるのもいいと思います

Debug.Print DBpath
Debug.Print "FileName = "; Dir(DBpath)
If Dir(DBpath) = "" Then MsgBox "ファイルを認識できません"

DBpath = "C:Data\0715単価管理.accdb"
adoCn.Open "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & DBpath & ";"
2

とりあえず、
貼り付けの場合は何もしない、
3行入力してあるときに、Enterキーを押したら次のテキストボックスへ移動するということだとして(カーソルがどこにあっても)、
下記のコードになります。

Private Sub テキスト1_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim s As String
    If KeyCode = vbKeyReturn Then
        s = Me.テキスト1.Text
        If Len(s) - Len(Replace(s, vbCrLf, "")) >= 4 Then
            KeyCode = 0
            Me.テキスト3.SetFocus
        End If
    End If
End Sub
1
hatena 2024/07/22 (月) 16:14:37 修正

Enterを押して3行目から4行目に移動するとき、4行目を作らず次のテキストボックスに移動できるようにしたいのですが、実現可能でしょうか?

3行までしか入力できないように制限したいということですね。
実現可能かといえば、可能です。
「キークリック時」のイベントプロシージャにコードを記述することになります。

「Enterを押して3行目から4行目に移動するとき」とのことですが、例えば下記のようなときにはどのような動作になることがご希望ですか。

カーソルがテキストの最後ではなく途中にあるときにEnterを押したとき(例えば、3行入力されていて、カーソル位置が2行目の真ん中でEnterを押す)

貼り付けで4行以上のテキストを貼り付けたとき、あるいは、貼り付けた結果4行以上になるとき。

7

解決済み

大変お世話になっております。
おっしゃる通り、新しいクエリを作成して1から同じように作り直したところうまく処理できるようになりました。
何が原因だったのでしょうか。。。
お騒がせしました。
ここの掲示板はいつも本当に頼りになります。
本当にどうもありがとうございました😌

6

提示されている情報をもとにサンプルを作成して実行してみましたが、問題なく更新できました。

更新前のテーブル
更新前のテーブル

更新クエリのSQL

UPDATE T90 SET [g] = "2024/06", T90.日付 = DateAdd("m",1,[日付]);

上記クエリをナビゲーションウィンドウでのダブルクリックで実行

更新クエリ実行後のテーブル

更新クエリ実行後のテーブル

つまり、提示されている情報での設計に問題はないです。

原因としては、
更新クエリが正しく実行されていないか、
更新後のデータの確認方法が正しくないか、
ぐらいしか思いつきません。

skさんの回答で提示されている情報を開示してください。

また、新規ファイルで、上記のようにテーブルと更新クエリを作成して実行したらどうなるかも試してみて結果を報告してください。

2
beginner 2024/07/12 (金) 15:40:57 ddfe5@79639

hirotonさん ありがとうございます。なるほど!テーブルに格納が簡単そうですね。全く思いつかないアイデアでした。試してみますね。

1
hiroton 2024/07/12 (金) 14:41:02 cda86@2ee8f

変数の適応範囲というものがあります。一般にスコープと言われます

スコープと可視性について

第108回.変数の適用範囲(スコープ,Private,Public)(エクセルの神髄 さん)

モジュールの先頭部分(プロシージャ外)にPublic宣言で変数を宣言すればどこからでも使える変数になります

宣言した後の使い方はほかの変数と同じです。ただし、パブリック変数は、プロシージャレベル変数として同名の変数を別途宣言することが可能なので、使用には注意が必要です

また、実行中に書き換えることのない値であれば変数ではなく定数で宣言するのが望ましいです

Public Const 共通保存フォルダ = "C:\Users\user\Desktop[フォルダー名]\"

宣言場所はどのモジュールでも変わりませんが、システム全体で共有されるものは、標準モジュールを追加して整理すると良いでしょう


ACCESSでこのようなデータを扱うなら、システム環境テーブルを作ってしまうのも手です

T_SYSENV

keyitem
共通保存フォルダC:\Users\user\Desktop[フォルダー名]\

テーブルに保存してあるデータはDLookup関数で参照できます。また、その機能をユーザー定義関数にしてしまえばそのほかの各モジュールで使う場合も使いやすくなります

Public Function getSysEnv(key As String)
    getSysEnv = DLookup("item", "T_SYSENV", "key='" & key & "'")
End Function
?getSysEnv("共通保存フォルダ")
C:\Users\user\Desktop[フォルダー名]\

テーブルに保存することによって、VBAを編集する必要がなくなる≒ランタイム環境でも(テーブルのデータを編集する機能を作っておけば)設定変更が可能になります

5

実行はしています

どのような状況下において、どのような操作によってその更新クエリを実行されたのかについて具体的に明記されることをお奨めします。

  • ナビゲーションウィンドウでその更新クエリを選択して実行した。

  • その更新クエリがデザインビューで表示されている状態において、[クエリ デザイン]タブ → [結果]グループ → [実行]をクリックした。

  • [クエリを開く]アクションを呼び出すマクロを実行した。

  • DoCmd.OpenQuery メソッドを呼び出すプロシージャを実行した。

  • 上記以外の実行操作。

現在はただ2024/05のデータが表示されるだけで更新がされません

また、更新クエリの実行結果をどのようにして確認されたのかについても明記して下さい。

  • 前述のいずれかの方法によって更新クエリを実行した後、ナビゲーションウィンドウからテーブル[T90]をデータシートビューで開いた。

  • テーブル[T90]をレコードソースとする帳票フォーム上において、更新クエリを呼び出すイベントマクロ、またはイベントプロシージャを実行した。

  • 上記以外の確認方法。

4

ありがとうございます。
SQLは名前違ってしまいましたがT90_テストとT90は同じものです
ごめんなさい
実行はしています
どうしても原因が分からなくて。。。

上のSQLだと、2024/05のデータを2024/06に更新したいのですが何か足りませんか?
現在はただ2024/05のデータが表示されるだけで更新がされません
宜しくお願いいたします。

3
hiroton 2024/07/11 (木) 17:46:29 edf98@f966d

エラーメッセージに限らず、正常に動作するはずの場合と比べておかしな動作をしている部分(動作/表示するはずなのに何も起きないモノ)を洗い出すと良いですよ

テーブルの内容をほかのテーブルの内容で更新する (Access)(Crie Anabukiさん)

正しく「実行」はしていますか?
実行時の確認メッセージは表示されますか?
メッセージに表示される件数は想定したものですか?


「T90_テスト」というテーブル

UPDATE T90 SET T90.年月 = "2024/06", T90.日付 = DateAdd("m",1,[日付]);

「T90」を更新しても「T90_テスト」が更新されることはありませんね

2

ありがとうございます
年月がテキストで日付が日付時刻型になります
SQLは以下のとおりです
エラーにはならず、なにも更新されません。。。

UPDATE T90 SET T90.年月 = "2024/06", T90.日付 = DateAdd("m",1,[日付]);

宜しくお願いいたします

1

「T90_テスト」の「年月」と「日付」フィールドのデータ型はそれぞれなんでしょうか。

あと、現状の更新クエリのSQLをコピーしてここに貼り付けてください。

エラーメッセージが表示されるなら、それも提示してください

4
nokonoko 2024/07/09 (火) 13:45:11 c9d3f@54883

情報ありがとうございました。
「閉じるときに最適化する」は未チェックでしたので、適用します。

3

注意点として、フロントエンドに作業用テーブルをおくと、データの追加削除が発生しますので、ゴミがたまりファイルサイズが肥大化するので、定期的にフロントエンドの最適化を実行する必要があります。
あるいは、オプションで閉じるときに最適化してもいいでしょう。

ACCESS 最適化でデータベースの容量を圧縮する方法 - たすけてACCESS

2
beginner 2024/07/09 (火) 12:43:40 ddfe5@79639

hatenaさん ありがとうございました。OpenArgsで簡単に解決しました。OpenArgsの事は知りませんでした。
こんな便利なことが出来る事を知ることが出来てありがたいです。
お世話になりました。

2
nokonoko 2024/07/09 (火) 12:11:04 c9d3f@54883

回答ありがとうございます。
すでに分割はしていましたが、作業用テーブルをフロントに置く考えがありませんでした。(全部まとめて分割していた)
これで解決できると思います。ありがとうございました。

1

複数人が同時にシステムを使うようになったら、
当然このT_製品仮登録内のデータが複数の作業者によって書き換えられてしまうことになります。

複数ユーザーがデータベースファイルを共有する場合は、「データベースの分割」をして運用することが推奨されています。

Access データベースを分割する - Microsoft サポート

ACCESS データベースを分割して複数人で共有する方法 - たすけてACCESS

サーバーにテーブルのみのデータベースファイルを置きます(バックエンドデータベース)
各クライアントにリンクテーブルとその他のオブジェクトをもつデータベースファイルを置きます(フロントエンドデータペース)

作業用のテーブルはフロントエンドデータベースに置けば、懸念する問題は発生しません。

1

フォーム上のコマンドボタンからDoCmd.OpenReportでレポートを開いていると仮定します。
DoCmd.OpenReportのOpenArgs引数で値を渡すことができますのでそれを利用するといいでしょう。

DoCmd.OpenReport メソッド (Access) | Microsoft Learn

コード例

フォームのコマンドボタンのクリック時

Private Sub コマンド1_Click()
    DoCmd.OpenReport "レポート名", acViewPreview, , , , Me.TX実施日.Value
End Sub

レポートの読み込み時イベント

Private Sub Report_Load()
    Me.実施日.Value = Me.OpenArgs
End Sub
2
驚天動地!前任者失踪丸 2024/07/04 (木) 18:55:43 23e8e@44ebd >> 1

お返事が遅くなり申し訳ございません。
回答ありがとうございます!
思い通りに背景色をつけられました。

1
hiroton 2024/07/03 (水) 10:10:26 f5027@f966d

日付の計算はとても一般的なので、標準機能が充実しています

適切な日付関数を選択する
(古いページのせいかなんかめちゃくちゃですね)

3年前の今日と比較する

[txb_最終出荷日]<DateAdd("yyyy",-3,Date())

Date 関数
DateAdd 関数


なお

?#2021/02/28#<dateadd("YYYY",-3,#2024/02/29#)
False
?dateadd("YYYY",-3,#2024/02/29#)
2021/02/28 

?#2021/02/28#<dateserial(2021,2,29)
True
?dateserial(2021,2,29)
2021/03/01 

DateAdd関数は、計算後の日付がその月の末日を超えてしまう場合、その月の末日に丸められます
存在しない月末日付の処理をどうするか?によって計算方法を変える必要がありますので、日付計算を行う場合は「月末」に注意してください
後述の対応をするなら

[txb_最終出荷日]<DateSerial(Year(Date())-3,Month(Date()),Day(Date()))
16
ビギナー 2024/06/27 (木) 15:09:49 ddfe5@b96a9

sk様 回答の表示はそういう事だったのですね。
変更用フォーム[S_1]の非連結コントロールは編集可能なのでユーザーでNullにされる可能性はありますので、変更実行ボタン(それに更新SQLコードを記載)に実行前にNull値には別のコントロール値(元から代入させていた)を代入する方法をとってます。

15

hatena様の分の前に詳しい回答を沢山頂いていたのを見落としてました。

それぞれの投稿の投稿者アイコンの下にある番号が、このスレッドにおける投稿順を示しています。

私が回答したのは hatena さん( 5 番)よりも後です。
ビギナーさんの投稿( 4 番)に返信する形を取ったため、その階層ツリーのノードとして表示されているだけです。

フォームAのレコードをダブルクリックで変更用のフォームS1が開き

[フォームA]がテーブル[T_1]をレコードソースとする帳票フォームであるとして、

元々のフォームA値をS1の別のテキストボックスに代入して
NULLのテキストボックスにはそれを代入

フォーム[S_1]の各非連結コントロールへの値の代入に際し、[フォームA]のカレントレコードから参照されたいずれかのフィールドの値が元から Null であるケースはないのでしょうか。

S1で変更しSQLで更新の仕組みにしてます。

少なくとも、フォーム[S_1]のいずれかの非連結コントロールの値がユーザーの操作によって Null にされる可能性はゼロではないはずです。

14
ビギナー 2024/06/27 (木) 12:23:22 ddfe5@b96a9

SK様 失礼しました。hatena様の分の前に詳しい回答を沢山頂いていたのを見落としてました。申し分けありません。
Null値の事は気になってました。説明不足でしたがフォームAのレコードをダブルクリックで変更用のフォームS1が開き、S1で変更しSQLで更新の仕組みにしてます。S1のNULL対策として元々のフォームA値をS1の別のテキストボックスに代入してNULLのテキストボックスにはそれを代入してから更新としてます。