Microsoft Access 掲示板

views
4 フォロー
5,901 件中 481 から 520 までを表示しています。
3
素朴な疑問マン 2024/01/29 (月) 11:03:39 23e8e@44ebd

貴重なご意見をありがとうございました。
壊れた時のリカバリー・オブジェクト数との兼ね合いを見て感が陽と思います。

6

それと”フォーカス喪失時”と”フォームの読み込み解除時”のイベントの違いを教えて頂けますでしょうか(知識不足でフォームの流れがわかっていないのですみません)。

一般論ではなく前回の回答の”フォーカス喪失時”と”フォームの読み込み解除時”についてということで回答します。

その前にメイン/サブフォーム形式のフォームのフォーカス関係のイベントについて。
まずフォームを開いた直後は、メインフォームのタブオーダーが1番目のコントロールにフォーカスがあります。
メインフォームの入力を終えてサブフォームの入力に移るためにサブフォームのコントロールをクリックしたとします。
フォーカス関係イベントは下記のように発生します。

メインフォーム上のサブフォームコントロールのフォーカス取得時(Enter)イベント

サブフォーム上のコントロールのフォーカス取得時(Enter)イベント

サブフォーム上のコントロールのフォーカス取得後(GotFocus)イベント

サブフォームの入力を終了してメインフォームのコマンドボタンやテキストボックスをクリックしてメインフォームへフォーカスを移動したとき

サブフォーム上のコントロールのフォーカス喪失時(Exit)イベント

サブフォーム上のコントロールのフォーカス喪失後(LostFocus)イベント

メインフォーム上のサブフォームコントロールのフォーカス喪失時(Exit)イベント※

クリックしたメインフォーム上のコントロールのフォーカス取得時(Enter)イベント

前回の回答では上記の※の時に、2つの合計をチェックして不一致の場合は、Cancel = Trueでイベントをキャンセルします。イベントがキャンセルされるとそれ以降のイベントは発生せずフォーカスはサブフォームから移動しません。

フォームの読み込み解除時イベントはフォームの右上のクローズボタンをクリックするなどフォームを閉じようとするアクションを起こすと発生します。サブフォームにフォーカスがある場合は、その前にメインフォームへフォーカスが移動することになります。イベントの発生順は下記のようになります。

サブフォーム上のコントロールのフォーカス喪失時(Exit)イベント

サブフォーム上のコントロールのフォーカス喪失後(LostFocus)イベント

メインフォーム上のサブフォームコントロールのフォーカス喪失時(Exit)イベント※

メインフォームの読み込み解除時(Unload)イベント

この場合も※のところで合計チェックをして不一致ならイベントをキャンセルしますが、読み込み解除時イベントは発生してしまいます。ということは合計が不一致のまま閉じてレコード保存されてしまうことになります。

それを防ぐために、読み込み解除時でも合計をチェックして不一致ならイベントをキャンセル(Cancel = True)してフォーカスをサブフォームへ戻しておきます。これで合計が不一致の場合はフォームを閉じることができなくなります。

5
ヒトシ 2024/01/29 (月) 10:40:26 ddfe5@72804

すみません、合計値が合致していない時は"F2とF4の合計が合っていません!"のメッセージが出て先に進めなくて狙い通りなのですが、合致している(正常の合計値)場合にフォーム閉じると ”メソッドまたはデータ メンバが見つかりません。” のコンパイルエラーとなり Private Sub Form_Unload(Cancel As Integer)のIf Me.埋め込み1(サブフォームコントロール名)の部分が示されます。メイン・サブに未入力で閉じても同じエラーとなります。
この回避はどうするといいでしょうか?

4
ヒトシ 2024/01/29 (月) 08:54:55 ddfe5@72804

ありがとうございます。[OldValue]の事は全くしりませんでした。イベント使わずに計算が反映しますので、これは便利です。それと”フォーカス喪失時”と”フォームの読み込み解除時”のイベントの違いを教えて頂けますでしょうか(知識不足でフォームの流れがわかっていないのですみません)。
あと質問と異なるのですが、このフォームでメインにだけ入力してサブにはレコードが1件もない状態を回避したい場合、どうすると効果的でしょうか?(閉じたり、メインレコード移動時にメッセージを出したい)

3

改善したいことはサブに金額入力したらすぐにサブフッターのテキストボックスに反映したい

Accessの仕様としては、F2、F4に金額を入力しただけではフッターの集計には反映されません。
レコード移動するとか、[Shift]+[Enter]キーを押す、レコードセレクタをクリック、・・・などなど
のレコード保存アクションを起こすと反映されます。

このレコード保存アクションを起こす前に、テキストボックスで金額を入力した直後に反映させたいなら、下記のリンク先の方法を参考にしてください。

フォームでの集計をレコード保存する前に反映させる - hatena chips

ただ、通常はそこまでしなくてもいいように思います。

合計値が合致していない状態でフォームを閉じたりメインに配置してます移動ボタン(新規レコード含む)で移動できない様に入力チェックが出来ないかなと思いまして。

サブフォームコントロールのフォーカス喪失時のイベントで合計値をチェックして合致していなかったら、イベントをキャンセルすればいいでしょう。
あとフォームの読み込み解除時でもチェックする必要があります。

サブフォームコントロール名(サブフォームを埋め込んでいるコントロールの名前)を「埋め込み1」、
サブフォームのフッターの集計テキストボックスの名前を SumF2, SumF4 と仮定した場合のサンプルコードです。
メインフォームのモジュールに記述します。

Private Sub Form_Unload(Cancel As Integer)
    If Me.埋め込み1.Form!SumF2.Value <> Me.埋め込み1.Form!SumF4.Value Then
        Cancel = True
        Me.埋め込み1.Form!SumF2.SetFocus
    End If
End Sub

Private Sub 埋め込み1_Exit(Cancel As Integer)
    Me.埋め込み1.Form.Requery 'レコード保存
    If Me.埋め込み1.Form!SumF2.Value <> Me.埋め込み1.Form!SumF4.Value Then
        Cancel = True
        MsgBox "F2とF4の合計が合っていません!"
    End If
End Sub

サブフォームコントロール名の確認法は下記を参考に。

サブフォームとサブフォームコントロールの違いとは? - hatena chips

2
Happy87 2024/01/26 (金) 16:20:02

hatenaさま

 早速なるお知恵を授けていただき、ありがとうございます(にっこり)。

 確かに!
 「テキスト(CSV)形式やAccessのテーブルとしてエクスポートする」のはアリ、充分実用性がありますね。

 またDB統合についても、現状ではファイルサイズが2GBを超えることは「まず、ありません」ので、
 大丈夫そうです。

 まずは状況を交通整理して、試してみようと思います。
 (備忘録、も参考にさせていただきます♪)

  今回のお知恵に感謝申し上げます(深々お辞儀)。

2
ヒトシ 2024/01/26 (金) 15:54:13 ddfe5@127a8

すみません説明不足でした。サブは下記のイメージです
F1   F2     F3    F4
摘要A  ¥100   摘要B   ¥50
摘要C  ¥20    摘要D   ¥70
このF2とF4の各合計値が合致する必要があります(サブフッターには各Sum値をテキストボックス)。金額入力ミスのチェックをしたいのです。
再更新ボタンもサブフッターに配置しており、単純に” Me.Requery” の記述だけです。
改善したいことはサブに金額入力したらすぐにサブフッターのテキストボックスに反映したいのと(再更新ボタン押さなくても)、合計値が合致していない状態でフォームを閉じたりメインに配置してます移動ボタン(新規レコード含む)で移動できない様に入力チェックが出来ないかなと思いまして。

1

1.バックアップ取得について

Excel形式でエクスポートではなくテキスト(CSV)形式にする
または、
Accessのテーブルとしてエクスポートする
とかでどうでしょう。

サイズ問題に関しては、
毎日1時間ごとにバックアップをとるということですよね。
バックアップとしてどのくらい以前のデータまでさかのぼる必要があるのか不明ですが、
例えば、
本日分と前日分は毎時間分(16ファイル)
それ以前は、その日の最終分の1ファイルを残して削除
1か月以前のファイルは、月初めのファイルのみ残して削除
1年以上前のファイルはすべて削除
というように決めておけば(一例ですので実情にあわせて)
無制限にバックアップのサイズが増えることはないので
現在のストレージの価格を考えたらそれほど負担ではないと思いますが。

2.DB統合について

二つのファイルを合わせても400MBぐらいなら、統合したとしてたぶん問題ないと思います。
テーブル設計がどうなっているのか不明ですので断言はできませんが、
自分の経験でいくとそのぐらいでインデックス破損やDBのアクセス遅延はないように思います。

Accessのファイルサイズ制限の2GBに近くなったら分割を検討するのでいいかと。

MS Office Accessのサイズが2GBを超えてしまったときの対処法 | 俺的備忘録 〜なんかいろいろ〜

1

「その合計が合致する必要がある」とは、具体的に何と何が一致する必要があるのでしょうか。
サブフォームのフッターに表示させているF2の集計値とF4の集計値でしょうか。

「F2、F4入力後すぐに計算」とは、F2テキストボックスで入力した直後(レコード保存する前)に集計値に反映させたいということでしょうか。

とりあえず「再更新(Requery)ボタン」に設定してあるコードを提示して、こ処理でどの部分をどのように改善したいのかを説明してもらうと回答しやすいです。

2

まずは、どの程度の規模のシステムなのかによるでしょう。
レポート数が一桁から20ぐらいまでなら、どちらでもいいでしょう。

レポート数が多数になると、名前付きクエリにしておくと、クエリ数も増えて管理が煩雑になります。
クエリ名を工夫してレポートの関係が分かるようにするという管理法もあるにはありますが。

私の設計したシステムの場合、レポート数100以上なんてのもありますので、ほとんど埋め込みクエリにします。
ただし、複数のフォームやクエリで共通で使うクエリは名前付きクエリにすることもあります。

1
hiroton 2024/01/24 (水) 20:00:44 b198c@a62fd

レポートのレコード ソースを設定する

名前付きクエリと埋め込みクエリの項目をチェックですね

どうでもいい経験談を加えると
「ACCESSが壊れた」とき、レコードソースプロパティが壊れてクエリがわからないなんてことには何度か遭遇してますね
名前付きクエリのSQLが壊れたのには遭遇したことはありません(偶々かもしれませんが)

1

「種別」テーブルと「商品リスト」テーブルがあってそれがコンボボックスの値集合ソースに設定されているということですか。

とりあえず一般的な設計法のサンプルです。
下記のようなテーブルを作成します。

T_種別

種別CD種別
1
2
 
T_商品
商品CD種別CD商品名
11AAA
21BBB
212あああ
502おおお
 
種別コンボボックス
---
名前 cmb種別
値集合ソース T_種別
連結列 1
列数 2
列幅 0cm

商品コンボボックス

名前 cmb商品
値集合ソース SELECT * FROM T_商品 WHERE 種別CD = [cmb種別];
連結列 1
列数 3
列幅 0cm;0cm

cmb商品のフォーカス取得時のイベントプロシージャを下記のように記述

Private Sub cmb商品_Enter()
    Me.cmb商品.Requery
End Sub
13
すずやん 2024/01/24 (水) 15:45:31 >> 11

すみません、追記させてください。
「\10.0.0.1\共有CSVフォルダ」が正常に表示されませんでした。
コードブロックとして再度記載します。

DoCmd.TransferText acImportDelim, "my_imp", "注文取込", "¥¥10.0.0.1¥共有CSVフォルダ¥注文.csv", False, ""

または

folderName = "¥¥10.0.0.1¥共有CSVフォルダ"
12
りんご 2024/01/24 (水) 13:36:38 935bc@0e907 >> 7

>> 8
じゃあ、各々のPCで取込・加工・登録が終わってから、各々でサーバ保管庫に投げておけばいいんじゃね?

9
タークン 2024/01/24 (水) 12:17:30 7a0a1@2705a

返信遅れて申し訳ございません。
配列と、連想配列まわりを、ゴニョゴニョやってました。

エクセルのシートを使用しないのが、大きな目的です。
そして、配列と連想配列はすごいです。

キーは重複できないという特性を利用すると、
とんでもない速度で集計できるようになりました。
文字列処理も、連想配列とjoinを使うと負荷が減るようです。

集計と編集をして、カンマ区切りの状態にしてから、
可視で確認するために、最終状態を一気にエクセルシートに張り付けると、
瞬きする間に処理が終了していました。

EXCELは応答していません、と表示されている時間は嘘のようです。

データに間違えが無ければ、エクセルに張り付けずに、
そのまま指定の形式のファイルに出力する方法に変更します。

データがさらに大きくなると、配列に読み込むこと自体に限界が来るようですが、
自己使用の目的だけであれば、VBAは遅いという事は無いと思います。
これを、EXCELと呼べるか微妙ではありますが、とにかくハイパフォーマンスです。

それ以上踏み込むか、とどまるかは目的と趣味の問題ですね。

11
すずやん 2024/01/24 (水) 10:30:17

ちょっとどの程度まで理解しておられるか分かりませんので、余談になるかもしれません。

会社のサーバー(ファイルサーバーか共有フォルダ、のはず)に置き、ということなので、同じネットワーク上にあるPCからでしたら、共有フォルダのアドレスは変わらないはずです。

例えば「10.0.0.1」というIPアドレスにある「共有CSVフォルダ」という共有フォルダの場合、どのPCからアクセスしてもアドレスは「\10.0.0.1\共有CSVフォルダ」ですよね。
※探し方は参考リンクを書いて頂いてますのでそちらを参照してください

ですの以下のように設定すればいいのではないでしょうか?

DoCmd.TransferText acImportDelim, "my_imp", "注文取込", "\10.0.0.1\共有CSVフォルダ\中略\注文.csv", False, ""

または

folderName = "\10.0.0.1\共有CSVフォルダ"

ただしAccessのプログラムをネットワークフォルダなどに置き、同時に複数人が使用すると不具合が発生します。例えばプログラムを使って同時に取り込み作業を行った場合、データベースに同時に書き込みが発生してしまい、壊れやすくなります。

参考:https://sys-daddy.com/multi-user-setting-of-access/

そこで「データベース分割」などが必要になってきます。
(でも書き込みを見ると、ある程度できているようですね)

10
hatena 2024/01/24 (水) 09:29:38 修正 >> 7

メインデータ.accdbはサーバーに置いてあり、作業用.accdbは各クライアントPCにおいてあるということでしょうか。

どういうことでしょうか?初学者なものでデータベース分割、リンクテーブルはよく理解しておりません。

複数ユーザーでデータを共有する場合は、データベースの分割は必須ですので、しっかり学習しておきましょう。WEB検索すれば解説ページは多数見つかります。

access データベースの分割 - Google 検索

9

はい、そうです。
アクセスの知識というよりサーバー上のファイルを共有する場合の前提知識ですね。

リンクテーブルにする場合もネットワークパス経由でリンクすることになります。

8

マスターテーブルと、取り込んだ注文.csvを加工して作成した注文データテーブルは、メインデータ.accdbに入ってり、テーブルのみのファイルになっています。他の作業用.accdbファイルではそのテーブルをリンクさせています。

7

どういうことでしょうか?初学者なものでデータベース分割、リンクテーブルはよく理解しておりません。

6

これをどうにか取得して、変数に入れるということですか?

5
りんご 2024/01/23 (火) 12:18:03 935bc@0e907

これってそもそもデータベース分割とリンクテーブルをきちんとやっているの?

1

Report_Closeイベントはキャンセルできません。
自動生成されたイベントプロシージャにCancel引数がないイベントはキャンセルできません。

読み込み解除時(Report_Unload)イベントならキャンセルできます。

Private Sub Report_Unload(Cancel As Integer)
   Dim res As String
    
    res = MsgBox("正常に印刷が完了しましたか?", vbQuestion + vbYesNo, "完了確認")
    
    If res = vbNo Then
    
        Cancel = True
        
    Else
    
        MsgBox "さようなら"
        
    End If
End Sub
3

現在は自身のPCのデスクトップ上のフォルダの中に注文.csvがあります。
このフォルダを会社のサーバーに移動させます。
Accessの入っている会社のPCならどれからでもこのコードが動くように、PCからそのサーバー上のフォルダまでのパスを取得したいです。

2

ちなみに、C:¥Users¥中略の部分を変数にするコードは下記のようになります。
ただし、質問のコードでエラーがでるならこのコードでもエラーはでます。
やっていることは同じことなので。

Private Sub btn_注文データ取り込み_Click()
    Dim folderName As String
    Dim oldname as String
    Dim newname as String
    folderName = "C:¥Users¥中略"
    DoCmd.TransferText acImportDelim, "my_imp", "注文取込", folderName & "¥注文.csv", False, ""
    DoCmd.OpenQuery "Q_注文取込→注文データ"
    DoCmd.OpenQuery "Q_注文取込削除"
    
    Kill folderName & "¥前回注文.csv"
    oldname = folderName & "¥注文.csv"
    newname = folderName & "¥前回注文.csv"
    Name oldname As newname
    
    MsgBox "取り込みが完了しました。", vbInformation + vbOKOnly, "取込完了"

End Sub
1

どのPCからでもということですが、これらのPCは同じローカルネットワーク内にあるということですか。
C:¥Users¥中略 というフォルダーはローカルネットワーク上の特定のPCのフォルダーということですか。

「どのPCからでもこのフォルダを扱えるよう」ということを上記の点も含めていもう少し詳しく説明してもらえますか。

自身のPC内のC:¥Users¥中略フォルダーでそこに注文.csvが存在するなら、そのコードではエラーにはならないと思いますが。

8

前の質問の時もそうでしたが、こちらの質問に対する応答がないですね。
結局、何がしたいのか、何が問題なのか不明のまま議論が深まらずに終了するということになってます。

配列をどうしたいのか、それが不明瞭のままです。これを明確にしてください。

避けて通るとEXCELに応答していませんと表示されるのを、

レコードセットのデータをエクセルに出力するというのが目的でしょうか。
だとしたら、skさんの回答の CopyFromRecordset を使う方法で簡単に実現できます。
連想配列を使う必要もないです。

7
タークン 2024/01/19 (金) 16:13:24 7a0a1@2705a

hatenaさん、すみませんでした。
連想配列の存在を知らなかったので、読み飛ばしていました。
分からないところが山もり状態ですが、
避けて通るとEXCELに応答していませんと表示されるのを、
数秒間眺めることになるので、なんとか理解します。
放置すると、動かなくなる日は近いはずなので。
ここをクリアしても、また限界が現れると思いますが、
配列周りの処理方法は、次の段階で役立つと思うので、取り組んでみます。

6

データと一緒に、フィールド名を格納することはできなかった

データを整理して一括で貼り付けないと

  • そもそもそのプロシージャはどのファイルのどのモジュールに記述されているのか( Access データベースファイル上の標準モジュール、Excelマクロ有効ブックの標準モジュールなど)。

  • 取得したレコードセット(の各フィールドの名前と値)をどこに、どのような形で貼り付けようとしているのか。

以上の前提についてのご説明がない限り、何を問題視されているのか不明瞭なままです。

例えば「ある accdb ファイル上に存在するテーブルから[sptx]、[sbj]、[pymt]、[fwd]、[dat]の 5 つのフィールドを選択し、全てのレコードを[id]の昇順に並べ替えた結果を取得して、新規ブック上のワークシートに複写するプロシージャを Excel マクロ有効ブック上の標準モジュールに作成しようとしている」といった場合であれば、2次元配列に拘らずとも、Excel.Range オブジェクトの CopyFromRecordset メソッドを使用する、といった方法もあるでしょう。

'ファイルパスとテーブル名は適宜書き換えること
Sub Test1()

    Dim strDatabasePath As String
    
    strDatabasePath = "C:\FolderName\FileName.accdb"
    
    If Dir(strDatabasePath) = "" Then
        MsgBox "Access データベースファイル'" & strDatabasePath & "'が見つかりません。", _
               vbExclamation, _
               "ファイル参照エラー"
        Exit Sub
    End If
    
    Dim adoCn As ADODB.Connection
    Dim strConnectString As String
    
    Set adoCn = New ADODB.Connection
    
    With adoCn
        .CursorLocation = adUseClient
        .CommandTimeout = 60
        strConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;" & _
                           "Data Source=" & strDatabasePath
        Debug.Print strConnectString
        .ConnectionString = strConnectString
        .Open
    End With
    
    Dim adoRs As ADODB.Recordset
    Dim strSQL As String
    
    Set adoRs = New ADODB.Recordset
       
    With adoRs
        Set .ActiveConnection = adoCn
        .CursorLocation = adUseClient
        .CursorType = adOpenStatic
        .LockType = adLockReadOnly
        strSQL = "SELECT t1.[sptx], t1.[sbj], t1.[pymt], t1.[fwd], t1.[dat]" & _
                 " FROM [テーブル名] t1" & _
                 " ORDER BY t1.[id];"
        Debug.Print strSQL
        .Source = strSQL
        .Open
    End With
    
    Dim adoFld As ADODB.Field
    Dim wbkDestination As Excel.Workbook
    Dim wsDestination As Excel.Worksheet
    Dim lngColumn As Long
    
    Set wbkDestination = Workbooks.Add
    Set wsDestination = wbkDestination.Worksheets(1)
    
    wsDestination.Cells(1, 1).Resize(1, adoRs.Fields.Count).NumberFormat = "@"
    For lngColumn = 1 To adoRs.Fields.Count
        Set adoFld = adoRs.Fields(lngColumn - 1)
        wsDestination.Cells(1, lngColumn).Value = adoFld.Name
        Set adoFld = Nothing
    Next
    
    wsDestination.Cells(2, 1).CopyFromRecordset adoRs
    wsDestination.UsedRange.EntireColumn.AutoFit
    
    adoRs.Close
    Set adoRs = Nothing
    adoCn.Close
    Set adoCn = Nothing
    
    Set wsDestination = Nothing
    Set wbkDestination = Nothing

End Sub
5
hatena 2024/01/19 (金) 15:08:03 修正

何番目に、どのフィールドをおいて呼び出したのか、
確認するコードを加えれば済む話ではあります。

そのコードを前の回答で提示したつもりですが。

どちらにしても、
2 次元配列をどのように利用しようとしているか。
レコードセットではだめなのか、その辺の説明がないと、
これ以上、議論のしようがないように思います。

4
りんご 2024/01/19 (金) 15:06:04 07313@0e907 >> 3

怪しい民間療法みたいな街角勉強会に引っかかっているんじゃないかしら?accessのようなデータベースがまだ発明されていない時代に、流行っていた思想は廃れたはずですが。

3
タークン 2024/01/19 (金) 14:38:38 7a0a1@2705a

まず、データと一緒に、フィールド名を格納することはできなかったようでした。
認識不足でした。

ACCESSのテーブルの、何番目のフィールドか調べたいわけではありません。
レコードセットは、フィールド名でデータを取り出せるので、
事前に、フィールドの並び順をカウントしておけば良いのですが、
よく単純な数え間違えが起こります。
何番目に、どのフィールドをおいて呼び出したのか、
確認するコードを加えれば済む話ではあります。
なのですが、フィールド名でデータを特定するのがベストなので、できればそうしたいということです。

と言っても、データを整理して一括で貼り付けないと、負荷はほとんど変わりません。
この処理段階の方が、何倍もミスを犯しやすいので、取るに足らないこだわりかもしれないです。

1

私はデザイン、レイアウトに力を入れてますよ。
ただし凝ったデザインにはしません。
シンプルでユーザーが使いやすいUIになるように意識してます。
例えば、下記とか。
入力必須項目のある入力フォームのUIを考察する - hatena chips

果ては白背景にテキストボックスの羅列、ラベルの見出しすらないものまであって辟易です(笑)

白背景にテキストボックスの羅列が使いにくいとは思いませんが、ラベルはあった方かいいでしょうね。

何かレイアウトのテンプレートを公開していらっしゃるサイト等、心あたりがありましたら教えて頂きたいです!

下記とか。

Accessフォームでおしゃれなデザインを作成 | 工場エンジニアのAccessスキル

ACCESS フォーム作成サンプル - たすけてACCESS

2

レコードセットは配列の上位互換だと思いますが、なぜ配列で処理する必要があるのでしょう?レコードセットならフィールド名でデータを取り出せます。どのような目的で配列にするのでしょうか。

やるとするなら、連想配列(Dictionary)にフィールド名と何列目かを格納して、参照することになるかな?

  Dim dic As Object
  Set dic = CreateObject("Scripting.Dictionary")
  Dim fld As ADODB.Field, i As Long
  For Each fld In adoRs.Fields
   dic(fld.Name) = i
    i = i + 1
  Next fld

  Debug.Print myArray(dic("フィールド名"), x)
1

sptx、sbj、pymt、fwd、datという5つのフィールド名のデータを2次配列に格納します。

myArray = adoRs.GetRows

具体的にどのような目的から 2 次元配列を用いようとされているのでしょうか。

"n1-" & i = myArray(0, x)

少なくとも、上記のコードをそのまま記述すればコンパイルエラーが発生します。

実際の場合は、フィールド数が多い場合が多いので、数字で指定するのは非効率的です。
フィールド名で指定してデータを取り出すのが、現実的な方法だと思います。

2 次元配列を使用する目的が不明ですので、今のところ評価のしようがありません。

2
nanana 2024/01/18 (木) 16:47:57 e48ae@9a838

ありがとうございます!頂いた情報をよく読み、チャレンジしてみます。

1
hiroton 2024/01/18 (木) 16:02:23 99b6e@f966d

とりあえずで回答しますが、孫フォルダを対象にしたいなら


Sub フォルダ名が売上データ○○になっているフォルダを取得する()

    Dim FSO As New FileSystemObject

    Dim 検索フォルダ As Folder
    Set 検索フォルダ = FSO.GetFolder("C:\Users\○○\Desktop\検索フォルダ")

    Dim 該当フォルダ As Folder
    Dim フォルダ候補 As Folder
    For Each フォルダ候補 In 検索フォルダ.SubFolders

        If フォルダ候補.Name Like "売上データ*" Then
            Set 該当フォルダ = フォルダ候補
            Exit For
        ElseIf
            'フォルダ候補(子フォルダ)を親として同じことをする

        End If

    Next

    If Not 該当フォルダ Is Nothing Then
        MsgBox "該当フォルダのパス:" & 該当フォルダ.Path
    End If

End Sub


とするだけですね

Sub フォルダ名が売上データ○○になっているフォルダを取得する()
    
    Dim FSO As New FileSystemObject
    
    Dim 検索フォルダ As Folder
    Set 検索フォルダ = FSO.GetFolder("C:\Users\○○\Desktop\検索フォルダ")
    
    Dim 該当フォルダ As Folder
    Dim フォルダ候補 As Folder
    For Each フォルダ候補 In 検索フォルダ.SubFolders
        
        If フォルダ候補.Name Like "売上データ*" Then
            Set 該当フォルダ = フォルダ候補
            Exit For
        ElseIf
            Dim 孫フォルダ As Folder
            For Each 孫フォルダ In フォルダ候補.SubFolders
                
                If フォルダ候補.Name Like "売上データ*" Then
                    Set 該当フォルダ = 孫フォルダ
                    Exit For
                End If
        
            Next
            If Not 該当フォルダ Is Nothing Then
                Exit For
            End If
        End If
        
    Next
    
    If Not 該当フォルダ Is Nothing Then
        MsgBox "該当フォルダのパス:" & 該当フォルダ.Path
    End If
    
End Sub

それぞれの変数がどのように使われるのか理解して、必要に応じて必要な変数を用意してください

ただし、別階層のフォルダを対象とするということは、同名のフォルダがある可能性が否定できないので、処理の順番によっては望んだ結果にならない場合もあります。また、「見つかったものは全て」というのが望みの場合もあるでしょう。仕様を明確にしましょう

20

最初の"T_入出庫一覧"テーブルを正規化すると下記のようになります。

T_区分マスター

区分CD区分
1入庫
2出庫
3保管
 
T_商品マスター
商品CD商品名
1AAA
2BBB
3CCC
4DDD
 
T_T_入出庫履歴
入出庫履歴ID区分CD移動日商品CD金額
112023/11/3012000
212023/11/3022000
312023/11/3032000
412023/11/3042000
522023/12/2154
622023/12/2254
722023/12/2354
822023/12/2454
922023/12/25181
1022023/12/25281
1122023/12/25381
1222023/12/25481
1322023/12/101108
1422023/12/102108
1522023/12/103108
1622023/12/104108
1722023/12/111135
1822023/12/112135
1922023/12/113135
2022023/12/114135

正規化についてはWEB検索すれば解説ページは多数見つかりますので、わかりやすそうな所をいろいろ見て理解を深めてください。
とりあえず下記を紹介しておきます。

正規化とは - もう一度学ぶMS-Access

正規化の実例 - もう一度学ぶMS-Access