Dim fileName As String
fileName = Dir(testPath)
Name testPath As Left(testPath, Len(testPath) - Len(fileName)) & Replace(fileName, "☆", "★")
起こりうること全部チェックするなら
Dim fileName As String
Dim folderPath As String
fileName = Dir(testPath)
folderPath = Left(testPath, Len(testPath) - Len(fileName))
fileName = Replace(fileName, "☆", "★")
If Dir(testPath) = "" Then
'元ファイルが存在しません
ElseIf Dir(folderPath & fileName) <> "" Then
'変更後のファイル名がすでに存在します
Else
On Error Resume Next
Name testPath As folderPath & fileName
If Err <> 0 Then
'予期せぬエラーが発生しました
End If
On Error Goto 0
End If
Private Sub PDF表示_Click()
Dim PDFPath As String, FldPath As String
PDFPath = Application.CurrentProject.Path & "\PDFDATA\" & MNFCTID & ".pdf"
FldPath = Application.CurrentProject.Path & "\PDFDATA"
If Not Dir(PDFPath) = "" Then
Shell "C:\Windows\explorer.exe " & PDFPath, vbNormalFocus
Else
MsgBox "データを探せませんでした。" & Chr(13) _
& "PDFフォルダを開きます。"
Shell "C:\Windows\explorer.exe " & FldPath, vbNormalFocus
End If
End Sub
これだけの情報では回答するのは難しいですね。
現状のテーブルと、そのデータ例を提示して、具体例で説明してもらえると回答できるかも知れません。
年末の忙しさも相まって、なかなか参考サイトを絞り込めずにいましたので非常に助かりました。
ありがとうございます。後程じっくり確認してみます!
今、ちょうど同じくACCESSの共有化等を検討しています。
もうご覧になっているかもしれませんが、こちらのサイト
に大変お世話になっていますので紹介しておきます。
mindwoodさん https://qiita.com/mindwood/items/062cde46b848d0c9e96a
詳しく解析していただき、ありがとうございます。
元のファイルを開いている等については考えていませんでした。
次にエラーが起きたとき、改めて確認したいと思います。
エラー対応のコードも組み込みたいと思います。ありがとうございます!
教えていただいた通りの方法で、希望のデータが作成できました!
自分では全く想像がつかなかった方法で、大変勉強になりました。
素早く教えていただけて本当に助かりました。ありがとうございました!
できました。リレーションシップで同じテーブルを複数登録できるのにはこういう意味があったのですね。
ありがとうございました。
いろいろありますが、SQLと連番テーブルを使う方法を紹介します。
まず、下記のようなテーブルを作成します。
テーブル名 T_連番
フィールド 連番 (数値型)
連番フィールドに 0から始まる連番を入力しします。予想される一人当たりの最大件数まで入力してください。
クエリを新規作成して、現在のテーブルと上記のT_連番を追加します。
クエリのデザインビューで下記のように設定します。
SQL文なら下記になります。
これでご希望のデータになります。
フォームも完成しました。
「1回の食事で1種類」でいいのなら、T_献立_料理 は不要になります。
T_献立 に 料理ID を追加すればいいでしょう。
T_献立
献立ID 主キー オートナンバー型
日付
料理ID
種別 (朝食、昼食、夕食など)
T_献立 をレコードソースとする入力フォームを作成すればいいでしょう。
料理IDはコンボボックスにして、料理名で選択できるようにしてもいいでしょう。
コンボボックスを2つ並べてIDでも料理名でも入力できるようにすることも可能です。
コードでも名称でも入力できるコンボボックス - hatena chips
リレーションシップ画面で、T_商品 と T_クラスマスタ を追加しで、クラス と クラスID を結合して「参照整合性」にチェックを入れます。ここまではできていますよね。
次に、テーブルの追加で、もう一回、 T_クラスマスタを追加します。 T_クラスマスタ_1 と別名がついて追加されます。
T_商品 と T_クラスマスタ_1 間で クラス と クラスID を結合して「参照整合性」にチェックを入れればいいでしょう。
お礼を返すのを忘れておりました。うまくいきました。ありがとうございました。
もしかして:
起こりうること全部チェックするなら
たとえば
testPath
が「C:\☆★☆注目☆★☆\☆hoge.dat
」だと変換後のパスは「C:\★★★注目★★★\★hoge.dat
」となります。大抵そんなフォルダないよって感じでエラーになります。もしかしませんか?あと、当たり前だけど
testPath
に"☆"
が含まれていないとName testPath As testPath
になるんでエラーになります最初のコードも2番目のコードもやっていること自体を変えている(ファイル名のみ
Replace
の対象とする)ので、フォルダ名も変換されるのが正しい処理なら最初のコードはもしかしません。2番目のコードにはフォルダの存在チェック処理を追加する必要があります予期せぬエラーについてはhatenaさん指摘の元ファイルが開いている場合の他、アクセス権の問題(書き込み許可がない)とかもあり得ます
システムでどこまで保証されているかによって必要なエラー対策は変わります。やりたいこととやっていることをもう一度見直して必要な処理を見極めてください
Name ステートメント (VBA) | Microsoft Docs
上記によると、エラーになる原因としては、下記の2点が考えられます。
それ以外のエラーについてはちょっと分かりません。
ありがとうございます。しかし、今回商品詳細ページを直に開く場合があるんでした。。
エラートラップオプションについて確認してみます。
1回の食事で1種類、30日分です。
質問のコードには4つの変数が含まれています。それぞれ中身はなんですか?
これに対してテストコードはきちんと同様の内容になっていますか?
DDEExecute
はどうやらExcel4.0マクロのコマンドが使えるようです。Workbook.Move
はシート移動のコマンドのようですテストコードは
としたら動作しませんか?
1回の食事の献立で、料理は必ず一種類だけ、ということてすか。
もし、そうなら、T_献立_料理 テーブルは不必要になります。
T_献立 に 料理ID フィールドを持たせるだけです。
そうでないなら(ふつうは複数の料理がでると思いますが)、
T_献立_料理 は必要です。
献立の入力フォームの作成について、これから解説しますが、今はちょっと忙しいので、今日の夜ぐらいになりますので、しばらくお待ちください。
分かりやすい説明ありがとうございます。全て真似事ですが作成できました。やはり献立が今一理解できません。12月17日の夕食の献立にカレー、サラダがある。仮にカレーしかなければ、毎日一食限定なら必要はないのでしょうか?献立はオートナンバーになっているので、12月17日はカレーとサラダだったと言うことがデータから分かると言うことなのでしょうか?簡単に2種類の料理名と材料名を入力しました。次はどうすればいいでしょうか?
丁寧な解説、ありがとうございます。本当に助かります。
ユーザーに多少の手間を取らせてしまいますが、とりあえず元データの
整理が完了するまでは、合致するデータが無かった場合に
該当するフォルダを開くようにします。
また、データ整理・および新たなデータを一気に登録する際には
改めてデータの参照方法を考えてみます。
本当に長々とお付き合いくださりありがとうございました。
良くない案1
フォルダをエクスプローラーで開く
良くない案2
ファイル名で近似値を求めてそのファイルを開く
例えば「B030b」を開こうとした場合、ファイルの一覧を降順に捜査して
の比較でそれっぽいファイルを見つけることはできます
複雑なことをしようとすればするほどさらなるイレギュラーが出たときに「思っていたのと違う。不具合だ」と言われるものです。全然いいアイディアになりません
本当の「いいアイディア」はPDFファイルを分割して保存しなおすことができないかを検討し、評価することでしょう
とはいっても、システムの運用開始はなるべく早くという要件もあるでしょうから、「製品ID.pdf」が見つからなかった場合はメッセージボックスを表示して(上記案のような)追加操作の実行を促す仕組みとすることはあると思います
過去の遺産の整理と並行して運用できるような限定的な仕組みという位置付けの機能としてしまいましょう
このテーブルから入力フォームを作成していくことになります。
まずは、料理に必要な材料を入力するフォームから作成していきましょう。
が、その前に、テーブルのフィールドにルックアップの設定をしておきましょう。
まず、T_料理 の「種別」フィールドのルックアップを下図のように設定します。
値集合ソースは
主菜;副菜;汁物
というようにセミコロンで区切ってリストを入力してください。これで、コンボボックスから選択できるようになります。
次に、T_料理_材料の「材料ID」フィールドのルックアップの設定を下図のようにします。
値集合タイプを「テーブル/クエリ」にして値集合ソースは「T_材料」とします。
列数: 2、列幅: 0 と設定することでコンボボックスのリストには「T_材料」の2番目のフィールドの材料名が表示されることになります。
テキストボックス部分にも材料名が表示されます。ただし、フィールドに実際に格納されている値は、材料IDになります。
この辺の設定の意味は理解するのが難しいと思いますが、おいおい理解できるようになるでしょう。
この設定でテーブルでの材料の入力が下記のようにコンボボックスから選択することできるようになります。
それぞれのテーブルの意味を簡単に説明しておきます。
T_料理、T_材料 はマスターテーブルと言われるもので、一度入力しためったに変更することのない固定的なデータになります。
T_献立 はトランザクションテーブルと呼ばれるもので、日々入力していってデータとして蓄積していくものになります。
T_献立 と T_献立_料理 の2つのテーブルは、「一対多の関係」といいます。
献立の1レコードに対して、複数の料理があるからです。
例えば、「12月17日の夕食の献立」に対して「カレーライス、サラダ」と2つの料理がある、という関係です。
T_献立が一側、T_献立_料理が多側になります。
T_料理 と T_材料 は「多対多の関係」になります。
例えば、カレーライスは、じゃがいも、人参、玉ねぎ、牛肉、カレールー の複数の材量が必要です。
逆に、じゃがいもは、カレーライスや肉じゃが、ポテトサラダ・・・などに使われます。
このような関係が「多対多」になります。
リレーショナルデータベースでは多対多の関係を実現することはできないので、2つのテーブルの間に入る中間テーブルというのを作成して、2つの「一対多の関係」に分解します。
T_T_料理_材料 というのが中間テーブルになります。
T_料理(一)---(多)T_T_料理_材料
T_材料(一)---(多)T_T_料理_材料
これらのテーブルにリレーションシップを設定すると、下図のようになります。
実はこの料理材料管理という題材は、かなり難易度が高いものになります。
テーブル設計も複雑になりますし、そこから管理用の入力フォームも作成するのも難しいものになります。
Accessで今まで何か作成したことがありますか。
名簿管理とか、家計簿(出納帳)とか、蔵書管理とか、、、この辺が最初に取り組む題材としては適切です。
入門書にのっているようなレベルのものを作成したことがあるのなら、次に取り組む題材として適切だとは思います。
解決したと思ったら、また壁が立ちはだかるのが世の常です。
サーバ内のPDFを漁っていたんですが、なんとPDFが結合されて100ページほどの1つのPDFとして
存在していました。
製品IDが「A001」「B158c」のような、頭はアルファベット、それ以降尾が数字(及び改訂)と
なっており、多くのPDFが「A001.pdf」みたいな都合の良い形をしていたんですが、
一部(というには多い)のデータが「B001~149.pdf」みたいな名前になってしまっていました。
PDFでしか生きていないデータもありますので、できればこの結合されたものを利用したいんですが、
なにかいいアイデアはありますか?
重ね重ね申し訳ありません。
30日分(全て一人前)を一回で買い物に行くとして、必要な材料の一覧を合算して抽出させたいのです。料理数もかなりの数があるので、料理名を入力するのではなく、簡単なコードを入力して抽出させる仕組みを作りたいのです。もちろん、それ以上に効率的に抽出できる仕組みでもいいです。料理の種類、料理名、材料名、個数、これらは必要だと思うんですが、これをどう作り繋げていけばのいいのかわかりません。
テーブルを作っていてわからなくなりました。献立テーブルと献立料理テーブルの必要性が。シンプルに30日分(30品目の料理)から必要な材料を合算して表示させたい。単位も統一して個単位でいいです。説明が下手で申し訳ございません。ご教示お願いいたします。
わかりました。やってみます。非常にわかりやすいです
検索フォームやメインフォームから開くときに、
検索だけなのか、編集等行いたいのかなどで場合分けをして、
開くのは同じフォームだけど、プロパティの設定変更から元データの保護等
ができるような形での実現で問題ないか、社内で相談してみます。
色々な考えの中から、最も適した構成を探すのに苦労しそうですが、
頑張ってみます。
ありがとうございました!
テーブル設計からということですね。
まずは、「正規化」という概念については理解していますか。
データベース設計の基本になります。よく、分からないという場合は、「テーブル 正規化」をキーワードでWEB検索して、解説ページをいくつか読んで、概要を理解しておいてください。(データベース初心者だと完全に理解するのは難しいと思いますので、なんとなくイメージとして掴んでおけばとりあえずOKです。)
例えば、下記のサイトの「正規化」の項目など。
もう一度学ぶMS-Access
そのうえで、最低限、下記のようなテーブルが必要です。
T_料理
料理ID 主キー
料理名
種別(主菜、副菜、汁物など)
T_材料
材料ID 主キー
材料名
単位
T_料理_材料
料理ID 主キー
材料ID 主キー
数量
T_献立
献立ID 主キー オートナンバー型
日付
種別 (朝食、昼食、夕食など)
T_献立_料理
献立ID 主キー
料理ID 主キー
上記のテーブルを作成したら、リレーションシップを設定します。
リレーションシップがよく分からないという場合は、上記で紹介したサイトの「リレーションシップ」の項目を参照してください。
とりあえずここまでやってみてください。それができたら、入力フォームの設計について説明します。
フォームの見た目が同じほうが良いのであれば、プロパティにレコードセットやデータ入力用などの作業を制限する仕組みがあるのでそれらを活用する形でいいかもしれませんね
下記でどうですか。
「F_商品」フォームは開いている必要があります。
Accessからパスの通し方は、一度大学の頃に研究室の部品管理用のQRコードを
Excelのハイパーリンクで一括で作ったことがあるので、なんとなくのイメージはできていました。
(同行内のID等から、文字式結合とかでつくろうかなぁとか)
データ管理に関しましては、PDFデータがてんでバラバラな箇所にしかないので、
今回新たに共通の保存場所を作ることにしようと思っています。
また、少し違う質問になってしまうのですが、
現フォームが、ヘッダに検索用スペース、詳細に検索結果、フッタに分割フォームの表の方
が表示されており、かつ、閲覧・編集兼用フォームなっています。
基本的に、閲覧用(検索用)と、編集用(登録用)は分けた方が良いのはわかりますが
検索だけのフォーム(検索TXTBOXと検索BTNだけ的な)にも分けるかどうかを
考えているところです。
あんまりフォームを分けすぎると、一部のユーザに混乱を与えそうですし、
上記の用に分けた場合のユーザビリティを自分の技量では保てない気がしてしまって。
直接の回答ではありません
デフォルトの設定だとクラスモジュールや別なフォームのモジュールのプロシージャを呼び出して、呼び出し先でエラーが発生すると呼び出し元の行が反転表示されます
オプションからエラートラップをクラスモジュールで中断に変更してエラー発生場所を確認してみてください
VBEのエラートラップオプションの違いについて(T'sWareさん)
ACCESS(データベース)の問題というよりはデータの一元管理の問題って感じです。まぁ、おのずと似たり寄ったりなものになると思いますが
具体的には「データベースの登録情報からPDFの保存パスを作る」感じになります。もっとも単純なのはPDFのファイル名は製品ID(+.pdf)とし、ACCESSファイルの置かれているフォルダに「PDFデータ」フォルダを作ってその中に保存する形
フルパスの保存なんかしなくてもデータベース上の製品IDがあれば
(ACCESSのパス)\PDFデータ\製品ID.pdf
でアクセスできますね。簡単です
データ管理がしっかりしているなら例えば
PDFデータ
└メーカー
_└製品区分
__└製品ID.pdf
なんてツリー構造で保存されていたりするでしょう。データベースでは製品テーブルに「メーカー、製品区分、製品ID」とフィールドを設けてやれば
(サーバーパス)\PDFデータ\メーカー\製品区分\製品ID.pdf
とPDFのパスが生成できます。データがしっかり管理されているのであればフルパスを保存しなくとも、「データベースとして正しい登録」をしてあげればファイルにアクセスすることができるわけです
そして、既にあるデータを活用したいと言われて大口取引先のデータは
「メーカー - プロジェクト名 - 製品シリーズ名 - 製品ID」
小口相手は
「メーカー - 年フォルダ - 製品ID」
のようなデータ管理を見て泣きを見ながらすり合わせをしていくわけです
なにか、フォームでのPDFの管理(パスを通す場合)で、いいアイデアや、基本的な
設計思想等がありましたら、後学のためにもお教えいただけると
幸甚に存じます。
よろしくお願いいたします。
hirotonさん、ありがとうございます。
今は直接埋込ですので、データ数が増えたときの不具合が心配で今回の質問に至りました。
常にフォーム内でPDFを表示したい、との要望でしたので、それを満たしつつ、データを
軽く(できればパスで通す)ような手が思い浮かばなかったのです。
しかしながら、先ほど社内で話し合った結果、フルパス(サーバ管理者との相談によっては相対パス)で
PDFへのリンクを貼り付けることにしました。
フォーム内にミニサイズでの表示はしないことにしました
(ユーザすべての言い分を聞いてられないという判断)
質問文の解釈にお手数おかけしてしまいましたが、今回の質問はこれで終わりにします。
ありがとうございました。
またAccessのDB管理が引き続くと思いますので、その際は以後宜しくお願い致します。
いい案ではないですが
この前提で「埋め込まない」をしようとすると、ACCESSにアクセス権の情報を含めることになります。ACCESSのセキュリティ性能を考えるとやるべきではありません。少なくともACCESS(データベース)のある場所のアクセス権は持っているユーザーを対象とすべきでしょう
そのうえで「埋め込まない」とするならACCESS(データベース)ある場所にサブフォルダを作ってPDF登録時にコピー、相対パスで保存とかでしょうか
これらUIの問題は埋め込みであるかどうかとは別な問題ですね。質問文前半からは「できている」ように見受けられますが問題になっているんでしょうか?
全くです。料理名、材料リストを作ったりしましたがそこからどうしていいかわからずです
全くです。料理名、材料リストを作ったりしましたがそこからどうしていいかわからずです
とかでどうでしょうか。
もっといい方法があるかもしれません。