Microsoft Access 掲示板

views
4 フォロー
6,278 件中 1,001 から 1,040 までを表示しています。
1
すずやん 2023/12/15 (金) 14:49:46

Accessにもあるみたいですね(使ったことはないですが)

https://kabudata-dll.com/ms-access/chart/

1

自己レスです。

個人的にこれまで考えたことが無かったのですが、こちらの記事が普通に参考になりました。
https://sourcedaddy.com/ms-access/understanding-module-load-demand.html

ちなみに AutoExec したところ、
私が作っていた小さなモジュール30程度は全て「開かれて」立ち上がりました。
巨大なモジュールが多数あれば、Access が選別するのかもしれません。

4
My Car Bomber 2023/12/15 (金) 11:46:37 7fdfc@46fae

お世話になっております。
意図した通りの出力結果が出るようになりました!ありがとうございました
何がどのように繋がって出力結果にたどり着いたのか、クエリやテーブルの構造・関数などを確認し勉強させて頂きます!

3
My Car Bomber 2023/12/14 (木) 14:21:41 7fdfc@46fae >> 1

ありがとうございます!
正規化されたテーブルを作るところからやってみます!

2
すずやん 2023/12/14 (木) 08:01:20

My Car Bomberさんの質問から発生する一連の構築に関する回答は、DBを使ったシステムのスタンダードかつお手本のような内容で素晴らしいですね。
出来上がればDBの速度低下で悩まされることも無く、カスタマイズもし易いシステムになりそうです。

1
hatena 2023/12/13 (水) 16:45:08 修正

まずは「T_取込」テーブルを正規化されたテーブルに変換します。
正規形のテーブルは記のようになります。

T_会社別売上 (テーブル名は適当ですので実態にあったものに変更してください。)

ID会社ID商品ID個数
1112
3121
4132
6141
7211

上記のフィールドも持つ空のテーブルを作成しておきます。
ID はオートナンバー型の主キーにしておきます。

下記のSQLのクエリを作成します。

SELECT
 会社マスター.会社ID,
 商品マスター.商品ID,
 Choose([商品ID],[商品1],[商品2],[商品3],[商品4]) AS 個数
FROM
 T_取込 INNER JOIN 会社マスター ON T_取込.社名 = 会社マスター.社名, 商品マスター
ORDER BY
 T_取込.取込ID, 会社マスター.会社ID, 商品マスター.商品ID;

これを保存してデータシートビューで希望のデータになっていることを確認したら、
追加クエリに変更して追加先を「T_会社別売上」テーブルにします。
この追加クエリを実行するとT_会社別売上に上記のデータ例のようにデータが追加されます。


下記のような数値型フィールドが一つのテーブルを作成します。
予想される最大個数までの連番を入力しておきます。

T_Num

Num
1
2
3
4
5

下記のようなSQLのクエリを作成すればレポート出力用にデータになります。

SELECT
 会社マスター.社名,
 会社マスター.[〒],
 会社マスター.住所1,
 商品マスター.商品名
FROM
  (T_会社別売上 INNER JOIN 会社マスター ON T_会社別売上.会社ID = 会社マスター.会社ID)
   INNER JOIN 商品マスター ON T_会社別売上.商品ID = 商品マスター.商品ID
  , T_Num
WHERE
 T_Num.Num<=[個数]
ORDER BY
 T_会社別売上.会社ID, T_会社別売上.商品ID, T_Num.Num;

これをレポートのレコードソースに設定すればいいでしょう。

2
あん 2023/12/13 (水) 12:39:43 b41ab@2928c

hatena様

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

ご指摘の通りやってみましたら、バッチリできました。

Set rst = rst.OpenRecordset で再設定しないといけない事を初めて知ったので勉強させてもらいました。
ありがとうございました!

助かりました。

1

DAOのRecordsetは、FilterプロパティやSortプロパティを設定したあと、再度開きなおさないと反映されません。
また、Nullは=演算子ではなくIs演算子で判定します。

        Set rst = Me.frm注文依頼発注用_一覧Sub.Form.RecordsetClone
        
        rst.Filter = "注文書作成チェック = True AND 発注ナンバー Is NULL"
        rst.Sort = "仕入先ID ASC,業務用品ID ASC,単位_注文数"
        Set rst = rst.OpenRecordset '←これが必要
        rst.MoveFirst
    
        Do Until rst.EOF


11
My Car Bomber 2023/12/13 (水) 08:32:33 7fdfc@46fae >> 8

大変参考になります、コードの内容理解に私では少し時間がかかりそうですが、読み解いてみます!

3
もっちー 2023/12/12 (火) 21:08:57 aef45@267c5

お返事遅くなりまして申し訳ございません。
こちらでできました。

作成日 > min(作成日)ですか、なるほどです。
どうもありがとうございます。

10

補足:

lngLastDataRow = .Cells(.Rows.Count, KeyColumn).End(xlUp).Row

事前バインディングではなく実行時バインディングを採用される場合は、Excel.XlDirection 列挙のメンバー定数 xlUp の代わりに値 -4162 を渡すようにして下さい。

9

1.B列の4行目からI列のB列最終行の範囲のみをインポートし、T_インポートテーブルにあるID、商品1、商品2、商品3、商品4フィールドに書き込みたいです。
2.また、T_インポートテーブルの依頼日フィールドに、B2セルの2023/12/12を入れたいです。

といった処理を実行したいなら以上のようなコードになるでしょう。

ただ、前回のスレッドにおいて

社名ID、社名、住所、TELフィールドを持つ社名マスター
商品ID、商品名フィールドを持つ商品マスターは作成しました

とご説明された通りなのであれば、正規化したテーブルに変換し、互いの[商品ID]同士で[商品マスター]と結合できるようにされた方がよいでしょう。

データ集計を行う上でも「発送用のレポート」を出力する上でも、その方が便利なのは明らかです。

8
'呼び出し例
Private Sub ImportTest1()

    Dim strTargetFilePath As String
    Dim strTargetSheetName As String
    Dim varRet As Variant

    strTargetFilePath = "C:\FolderName\BookName.xlsx"
    strTargetSheetName = "Sheet1"

    varRet = ImportOrderRecords(strTargetFilePath, _
                                strTargetSheetName)

    If IsNull(varRet) = False Then
        MsgBox strTargetFilePath & " の " & _
               strTargetSheetName & " から " & _
               varRet & " 件のレコードを取り込みました。", _
               vbInformation, _
               "実行完了"
    End If

End Sub
7
Function ImportOrderRecords(SourceBookPath As String, SourceSheetName As String)
On Error GoTo Err_ImportOrderRecords

    Const OrderDateCellAddress As String = "B2"
    Const OrderDateSuffix As String = "依頼分"
    Const HeaderRow As Long = 4
    Const KeyColumn As Long = 2
    Const DestinationTableName As String = "T_インポートテーブル"

    ImportOrderRecords = Null

    Dim xlsApp As Object        'Excel.Application
    Dim xlsBook As Object       'Excel.Workbook
    Dim xlsWorksheet As Object  'Excel.Worksheet

    Set xlsApp = CreateObject("Excel.Application")

    Set xlsBook = xlsApp.Workbooks.Open(FileName:=SourceBookPath, ReadOnly:=True)
    Set xlsWorksheet = xlsBook.Worksheets(SourceSheetName)

    Dim varOrderDate As Variant
    Dim lngSuffixPostion As Long

    With xlsWorksheet.Range(OrderDateCellAddress)
        
        varOrderDate = .Value
        lngSuffixPostion = InStrRev(varOrderDate, OrderDateSuffix, -1, vbTextCompare)
        
        If lngSuffixPostion > 0 Then
            varOrderDate = Trim(Left(varOrderDate, lngSuffixPostion - 1))
        End If
        
        If IsDate(varOrderDate) = True Then
            varOrderDate = CDate(varOrderDate)
        Else
            Debug.Print .Address(False, False) & " セルの値: "
            Debug.Print .Value
            MsgBox .Address(False, False) & " セルから依頼日を参照できません。", _
                   vbExclamation, _
                   "ImportOrderRecords"
            Set xlsWorksheet = Nothing
            xlsBook.Close False
            Set xlsBook = Nothing
            xlsApp.Quit
            Set xlsApp = Nothing
            Exit Function
        End If

    End With

    Dim lngFirstDataRow As Long
    Dim lngLastDataRow As Long

    With xlsWorksheet
        
        lngFirstDataRow = HeaderRow + 1
        lngLastDataRow = .Cells(.Rows.Count, KeyColumn).End(xlUp).Row
        
        If lngFirstDataRow > lngLastDataRow Then
            MsgBox "ワークシート[" & .Name & "]からデータ行を参照できません。", _
                   vbExclamation, _
                   "データ参照エラー (ImportOrderRecords)"
            Set xlsWorksheet = Nothing
            xlsBook.Close False
            Set xlsBook = Nothing
            xlsApp.Quit
            Set xlsApp = Nothing
            Exit Function
        End If
        
    End With

    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim strSQL As String

    Set db = CurrentDb

    strSQL = "DELETE * FROM [" & DestinationTableName & "]"
    Debug.Print strSQL
    db.Execute strSQL, dbFailOnError

    strSQL = "SELECT * FROM [" & DestinationTableName & "]"
    Debug.Print strSQL

    Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)

    Dim lngDataRow As Long
    Dim lngInsertCount As Long

    For lngDataRow = lngFirstDataRow To lngLastDataRow
        rs.AddNew
        rs![依頼日].Value = varOrderDate
        With xlsWorksheet.Cells(lngDataRow, KeyColumn)
            rs![社名ID].Value = .Value
            rs![商品名1].Value = .Offset(0, 4).Value
            rs![商品名2].Value = .Offset(0, 5).Value
            rs![商品名3].Value = .Offset(0, 6).Value
            rs![商品名4].Value = .Offset(0, 7).Value
        End With
        rs.Update
        lngInsertCount = lngInsertCount + 1
        Debug.Print lngInsertCount & " 件目のレコードを取り込みました。"
    Next

    ImportOrderRecords = lngInsertCount

Exit_ImportOrderRecords:
On Error Resume Next

    Set rs = Nothing
    Set db = Nothing

    Set xlsWorksheet = Nothing

    If Not xlsBook Is Nothing Then
        xlsBook.Close False
        Set xlsBook = Nothing
    End If

    If Not xlsApp Is Nothing Then
        xlsApp.Quit
        Set xlsApp = Nothing
    End If

    Exit Function

Err_ImportOrderRecords:

    Dim strErrMsg As String

    strErrMsg = Err.Number & ": " & Err.Description

    MsgBox strErrMsg, _
           vbCritical, _
           "実行時エラー (ImportOrderRecords)"

    Resume Exit_ImportOrderRecords
End Function
6

エクセルの方は変更できないということであれば、アクセスにインポートしてから、アクセスの方で正規化変換することになります。
Accessではレポートに出力するだけで、出力レイアウトがエクセルの表とほぼ同じということなら必要ないです。
ただ、せっかくアクセスにインポートするならデータベースとして活用したいですよね。
印刷だけなら、エクセルでもできますので。

シートの範囲指定してインポートするなら、TransferSpreadsheet で第6引数でシートや範囲を指定できます。

DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "テーブル名", "Excelファイル名", False, "シート名$B4:I"

上記はB列からI列の4行目からデータのある最後までインポートします。

5
My Car Bomber 2023/12/12 (火) 11:01:07 7fdfc@46fae

シートの形式を変更したり、シートを手作業で加工して名前を付けたりすることは出来ないという前提でお願いします。
そのため、任意の範囲のみをインポートする方法を模索しています。

正規化というのは、今回でいえば、A列と1~3行目が無ければ正規化できているということになりますか?

4

エクセルの表のフォーマットがデータベースとしては扱いにくい形になってます。
データベース用語とて「正規化」ができていない状態です。
もし、エクセルの表の形式を変更できるならそれを検討してみてはどうでしょう。
banjoさんの回答も同じ意味だと思います。

もし、エクセルの表のフォーマットは変更不可ということなら、
表範囲に名前をつけることはできないでしょうか。
表範囲をテーブルにできないでしょうか。
(テーブルにすれば自動で名前がつきます。)

そうすれば、インポートするときにその名前を指定してインポートできます。

3
banjo 2023/12/12 (火) 10:18:47 d32ed@4d71e

「初心者なもの」の実際のところがよく分からないので、釈迦に説法だったらすみません。

ExcelやAccessは集計が得意です。しかし、集計後のデータから集計前を復元することは困難または不可能です。
My Car Bomberさんの例であれば、
今あるもの → 今欲しいもの への加工は苦手(機能を自分で作らないといけない)ですが、
今欲しいもの → 今あるもの への加工は得意(機能が用意されている)です。

My Car Bomberさんが例えば
依頼ID 依頼日 取引先ID 商品ID
などと入力するようにすれば、「今あるもの」がすぐに得られるだけでなく、
さまざまな区間(日、月、年他任意の区間)で集計がすぐに得られると思いますが、
切り替える価値がありそうか検討してみて下さい。
(依頼日を Date や CTRL + ; で入力できるし、他でも支援ができます)

2
My Car Bomber 2023/12/12 (火) 08:41:42 7fdfc@46fae >> 1

初心者なもので仰っていることがあまり理解できず申し訳ありません。
詳しく説明を頂けるとありがたいです!

1
banjo 2023/12/12 (火) 04:51:05 32db9@8d677

横ですが、これは運用を変えられないのでしょうか。
「今欲しがってるもの」→ExcelのピボットテーブルやAccessのクロス集計クエリ→「今あるもの」
なので、「今欲しがってるもの」をベースに変更できないのでしょうか。
メリットとして、商品を柔軟に増やせるなんてのもありますが。

20
すずやん 2023/12/11 (月) 17:45:12 >> 19

他の方々が疑問として提示されている内容や、アドバイスの内容と、それに対するタークンさんのコメントがかなり食い違っている感があります。
再度何に対してアドバイスされているのかをしっかり理解してみてください。

Excelでのファイルの出力方法は、「メニューのファイルから保存」するだけではありません。例えばExcelでVBAを使用することでCSVを出力できますが、これも試されましたか?
他、「届書作成プログラム」で出力したファイルに上書きする方法ではどうでしょうか?

Excelから出力したCSVファイルの16進コードや文字コードが「届書作成プログラム」で出力したファイルと比較して変わっていないかなどを確認するのも良いかもしれません。

※ちなみに「EXCELL」ではなく「Excel」です(「l」が多い)

19
タークン 2023/12/11 (月) 16:08:40 7a0a1@2705a

届書作成プログラムのフォーマットが特殊なのでしょう。
OFFICEが利用できないアプリは、バグに近い仕様だと思います。
文字コードの仕様など、基礎的なことは確認済みです。
届書作成プログラムで吐き出したファイルを、
EXCELLに取り込んで、別名保存でCSVにした段階で、読み込めないファイルになるので、
原因は分からないが、EXCELL使ったらダメなんだなという判断は、正しいと思います。
もちろん、コードで処理しようが、手作業で別名で保存にしようが同じです。
テキストにした時点で、属性は無くなるはずなので、何か他の事が原因なのでしょう。
一番懸念しているのは、ACCESSのデータベースを使った時点でNGみたいなことが起きたら、
コスト的に自動化は放棄するしかないという事です。
すごく心配です。

いつ、電子申請が義務化されてもおかしくないので、
何とかしてほしいですが、行政に利用者の声など届きません。

5
My Car Bomber 2023/12/11 (月) 13:43:25 7fdfc@46fae >> 2

概ねそんな感じのレイアウトで、A列も空白になっています。
いままでExcel上で整形してから取込むといったことしかしてこなかったので、どうすれば自動で4行目のフィールドからとりこめるのか分かりません。

18

hirotonは「届書作成プログラム」に携わった人間ではありません。それが何を言っているのかもわかりません

CSV」がなんなのか学習してください。そのうえで「CSV出力に必要なもの」は質問者が提示してください


hirotonはこの場で誰かの文句に変わって仕事をするつもりなどありません

17

いろいろな話がごっちゃになってます。

最初の質問の「タイムカードデータの入力」はRecordsetで解決ということですよね。

そこから、派生的に下記のような流れになってます。

それは分かっているのですが、Recordsetで開きたくないのです。
Recordsetで開くと、データが多い場合はストレスを感じます。

処理の内容しだい。Recordsetの方が速い場合もあるし、SQLの方が速い場合もあります。

他の用途のために、可能な限りシートに展開しないで、処理しようと思っているだけです。

シートのセルを一つずつアクセスするような処理にするとたしかに重くなります。
パワークエリを使う、配列で処理する、Dictionaryオブジェクトを使う・・・など高速化の手段はいくらでもあります。

Functionで配列を使用すると、いきなり重くなったりするので、

どのような処理か不明ですが、使い方が悪いのだと思います。
正しく使えばたいていの処理は劇的にはやくなります。

実は、社会保険の電子申請する届出書作成アプリは、
EXCELLをCSVに変換したファイルだとUPできないという、
ほぼ不良品に近い欠点があるのです。
何十億もかけて始めた労働厚生省のアプリです。

おそらくそのアプリがCSVの標準から外れたものなのか、CSVへの変換設定に間違いがあるのか、・・・
Excelの欠点ではなく、そのアプリの欠陥ですよね。
どちらにしてもいいまでの流れからまったく関係ない話です。

100項目以上のヘーダーが無いCSVファイルを作るプログラムを3日かけて作ったあげく、

エクセルVBAで作ったということですか?

しかし、この問題を解決するには、
タイムカードを他の言語で作るしか無いので、

なぜ、このような結論になるのか分かりません。
エクセルVBAでも「100項目以上のヘーダーが無いCSVファイル」は可能です。
あるいはヘッダー付きで出力してあとからヘッダーのみ削除してもいいですね。

届書作成プログラムでは、
EXCELLからCSVファイルに変換したファイルは読み込めないと言っているのです。

エクセルのCSVファイルの出力は、CSVとしては標準的なものだと思いますので、
届書作成プログラムのフォーマットが特殊なのでは。
だとしたらVBAでテキスト出力プログラムを作成することは可能ですので、特殊な書式に合わせて出力することも可能です。

「届書作成プログラムにUPでるCSVの作り方」をご存じのようなので、ぜひともご教授ください。

そのCSVの仕様、出力サンプル、元となるエクセルデータなどを提示されたら回答はつくと思いますよ。

16
タークン 2023/12/09 (土) 16:33:22 7a0a1@2705a

EXCELLをこきおろしているわけではありません。
届書作成プログラムでは、
EXCELLからCSVファイルに変換したファイルは読み込めないと言っているのです。
これは、上席のサポートの人も、認めている事です。
「届書作成プログラムにUPでるCSVの作り方」をご存じのようなので、ぜひともご教授ください。
労働厚生省も、喜ぶはずです。

2
banjo 2023/12/09 (土) 15:19:07 dff57@9daea

>hatena様
私もそういう実装だと思っていたので、
ヘルプや検索してすぐに見つかった記事……例えばADOを解説した(だいぶ古い)記事で
こういうのを見つけて もやもや しました。「的」を使ってこの解説です。

Windows 2000 - Development Guide for Business Applications
https://www.itmedia.co.jp/help/howto/win/win2000/0007special/complus_vb/chap1/05.html

排他的ロックと共有的ロックのどちらを使うのかは,場合によって異なる。排他的ロックを使った場合には,誰かが編集作業に入ると,ほかのユーザーはそのレコードにアクセスできなくなる(書き込みだけでなく読み取りも不可になる)。

引用した MS Learn の一つは「適用先: Access 2013」と明記があるのですが、
「(バックエンドの)DBによって実装が違う」のかよく分からないのが困り物です。
昨日は rs.Supports(adResync) が True でも Resync が機能しなくて悩みましたし……
PostgreSQL でも入れて比較すればいいじゃん、と言われればそうなのですが……

ともあれ、hatena さんもそういうご見解であれば安心です。
ありがとうございました。

1

公式の解説はなんかわかりにくいですね
排他ロック、共有ロックとはいってなくて排他的ロック、共有的ロックと濁してます。

定数のOptimistic、Pessimisticは楽観的、悲観的という意味なので、楽観ロックと悲観ロックの違いで意味を調べた方がいいように思います。

排他制御 悲観ロック 楽韓ロック - Google 検索

上記のリンク先をいろいろ見たけど、悲観ロックに関して読み取りまで禁止するかどうかは、ぶれがあるようです。DBによって実装が違うのでしょうか。

質問のMSの公式のリンク先の説明では
「レコードごとのペシミスティック ロックを示します。」
「レコード単位の排他的ロックを指定します。」
とレコード単位でのロックとしてます。
だとするとレコード単位で読み取りを許可しない(編集中のレコードのみ表示されない)という実装は考えにくいので、他ユーザーのレコードの読み取りは許可するが、更新はできない、という実装かと推測されます。

私はこのような理解でおりますが、どうでしょうか。

4
ABCDEFGHI
1注文数量
22023/12/8注文
3
4No社名住所TELりんごぶどうみかん
51A社000-0000東京00-00001221
62B社000-0001京都00-00011111
73C社000-0002大阪00-00021111

参照元のExcelワークシートが上記のようなレイアウトになっている、
ということなのであれば、少なくとも Access のテーブルへの取込は
オートメーションによって行うことになるでしょう。

Excelワークシートからデータを取り込んだテーブルを使用して
レポートへの出力を行う処理については、それとはまた別の問題です。

3
すずやん 2023/12/08 (金) 14:09:26

わたしが構築する場合は、という想定で記載してみます。
他に良い方法はいくらでもあると思うので、あくまで参考までに。

※Excelからインポートした後

既存のテーブル:
T-INPORT:インポートしたテーブル
M-社名:社名マスター
M-商品:商品マスター

作るテーブル:
T-購入履歴:インポートしたテーブルから購入された情報を抽出するテーブル
項目:「ID」「社名ID」「商品名ID」

作るView:
V-発送用レポート:発送用のレポートのレコードソース

発送用のレポート:
発送レポート

1.まずT-INPORTから1行、読みます。

2.T-INPORTの「社名」とM-社名を比較し、社名マスターのIDを取得します。これは変数に一時保持します。

3.T-INPORTの「りんご」の個数をもとに「りんごの商品ID」「社名のID」「個数」を関数に渡します

 ※上記の「関数」とは渡された引数をもとに「T-購入履歴」に情報を書き込む機能です
  中では「個数」の回数分、「T-購入履歴」に書き込みが発生します。

4.T-INPORTの「梨」の個数をもとに「梨の商品ID」「個数」「社名のID」を関数に渡します
※以下「ぶどう」「みかん」同じ

5.「4.」が終わったら、「T-購入履歴」と「M-社名」「M-商品」をViewで連結した「V-発送用レポート」に中身が発生していると思いますので、これをもとに「発送レポート」を出力します。

以上です。

これだと品目が増えるとプログラムの修正が必要なので、かなり力技です。
が、とりあえずなんとかなるかと思います。

2
My Car Bomber 2023/12/08 (金) 13:58:40 7fdfc@46fae >> 1

Excelファイル自体は加工を行わず、インポート時に必要なフィールドだけを取り込み、それを加工してレコードソースを作成したいです。

注文数量(タイトル行)
2023/12/08 注文
(空白行)
No 社名   〒  住所   TEL  りんご  梨  ぶどう みかん
1 A社 000-0000 東京 00-0000   1   2   2   1
2 B社 000-0001 京都 00-0001   1   1   1   1
3 C社 000-0002 大阪 00-0002   1   1   1   1

1. Excel取込フォームの取込ボタンのクリック時イベントで↑のExcelファイルを選択

T_取込テーブル

取込ID  ID  りんご 梨 ぶどう みかん 注文日
 1   1    1   2   2    1  2023/12/08
 2   2    1   1   1    1  2023/12/08
 3   3    1   1   1    1  2023/12/08

2. ExcelファイルからID、りんご、梨、ぶどう、みかんのフィールドをインポートしてT_取込テーブルに追加(注文日はExcelファイル2行目の日付を入れる)

T_ラベル出力用

ラベルID 社名  〒    住所  TEL   商品
  1  A社 000-0000 東京 00-0000 りんご
  2  A社 000-0000 東京 00-0000 梨
  3  A社 000-0000 東京 00-0000 梨
  4  A社 000-0000 東京 00-0000 ぶどう
  5  A社 000-0000 東京 00-0000 ぶどう
  6  A社 000-0000 東京 00-0000 みかん
  7  B社 000-0001 京都 00-0001 りんご
  8  B社 000-0001 京都 00-0001 梨
  ・
  ・
  ・

T_取込テーブルとマスターで↑のようなレコードを作り、ラベルシール出力用レポートのレコードソースにしたいです。

1

できるだけクエリのみで解決したいのか、VBAを使用してもよいかによって
提示される解決方法は異なります。

上記のようなテーブルをExcelからインポート

大元のデータがExcelワークシート上のテーブルなのであれば、
先に Power Query によってそのような形に変換されたテーブルを
Access データベースにインポートする、という選択肢もあるでしょう。

3
banjo 2023/12/08 (金) 07:29:41 47096@237a3

ちなみに 1 の投稿は、ヘルプの「このメソッドは、静的または前方専用のカーソルを使用していて、基になるデータベースの変更を確認する場合に役立ちます。」直後の「読み取り専用ではない Recordset オブジェクトに対してのみ使用できます。」の意味が解らなかった、というものです。

う~ん

2
banjo 2023/12/08 (金) 07:26:06 47096@237a3

すみません自己レスです。
rs.open の引数を網羅テストしたら、事情が解りました。
rs.Supports(adResync)は、何故かただの飾りでした。
rs.resync は、JET(ACE)であっても、特定のパターン内で使えるようです。

2
banjo 2023/12/08 (金) 05:44:15 7ca94@237a3

コピペバッファが古かったです。作成日のところは「作成日 >」です。

1
banjo 2023/12/08 (金) 05:41:31 7ca94@237a3

これでどうでしょうか? 簡単に動作試験しましたが、DELETEがあるので 慎 重 に(!)検討して下さい。

DELETE * FROM 参照1 AS OT
WHERE 作成日 = (
 SELECT MIN(作成日) FROM 参照1 AS IT
 WHERE OT.会社ID=IT.会社ID AND OT.組織ID=IT.組織ID AND OT.職員ID=IT.職員ID
)

1
banjo 2023/12/08 (金) 04:53:45 7ca94@237a3

Resync メソッド (ADO) | Microsoft Learn
https://learn.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/resync-method-ado
>CursorLocation プロパティを adUseClient に設定した場合には、 Resync は、読み取り専用ではない Recordset オブジェクトに対してのみ使用できます。

という分かりにくい文章もあったので
    With cn
        .CursorLocation = adUseServer
        .Open "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=(略)"
    End With
のパターンも試しましたが、今度は False → 同じエラーでした。
本当に分かりません……

15
hiroton 2023/12/07 (木) 10:52:53 b2344@f966d

EXCEL(ECXEL VBA)もそんなに遅いモノじゃありません

「簡単に出来るがクッソ遅い処理」は簡単にできます。とにかく簡単にいろんなことができるソフトなので。速さが欲しいならそれなりに仕様を勉強する必要があります
こういうのとか

EXCELLをCSVに変換したファイルだとUPできない

EXCELからCSVを出力する方法もいろいろあります。「UPできないCSVの作り方」しか知らないだけですね
そもそも、CSVがなんたるか?を学べば、ただCSVと言っただけで常に互換が可能だという考えも知識不足だということがわかります。EXCELを問題にするのはお門違いでしょう

何をもってEXCELをこき下ろしてるのかわかりませんが、まぁ、Pythonが都合がよさそうだということであればそれでいいんじゃないですかね

あと、ここはACCESSの掲示板なので、EXCELでどうのこうの言いたいのなら別の場所を探したほうがいいと思いますよ

14
タークン 2023/12/07 (木) 10:30:11 7a0a1@2705a

ありがとうございます。
EXCELLのシートを利用しなければ、ほかの言語との処理速度に大差はないはずなので、
データを格納する方法を覚えつつ、申告対策としてPythonあたりを始めてみます。
実は、社会保険の電子申請する届出書作成アプリは、
EXCELLをCSVに変換したファイルだとUPできないという、
ほぼ不良品に近い欠点があるのです。
何十億もかけて始めた労働厚生省のアプリです。

100項目以上のヘーダーが無いCSVファイルを作るプログラムを3日かけて作ったあげく、
サポートダイアルの責任者から、使い物にならないという回答をいただきました。
直接、テキストに出力するしかないのです。
正直、怒りが収まりませんでした。

しかし、この問題を解決するには、
タイムカードを他の言語で作るしか無いので、
両方始めてみようと思います。

13

タイムカードなら、Recordsetで十分です。
簡単なので、むしろ有りだと思います。
他の用途のために、可能な限りシートに展開しないで、処理しようと思っているだけです。

あっ、別の話になっていたのですね。

Functionで配列を使用すると、いきなり重くなったりするので、

配列は高速化のための有用なツールです。
ツールの使い方を間違っているのかも。

今回はRecordsetで解決ということなので、これにて。