Microsoft Access 掲示板

連想配列のキーに、以上や以下の要素を使う方法(PDF内の表をAccessに取り込んで活用したい)

9 コメント
views
4 フォロー

    If x  < 63000 Then
        gr = 1
      Else
        If x >= 63000 And x < 73000 Then
            gr = 2
       Else
         If x >= 73000 And x < 83000 Then
             gr = 3
      End if

非常に簡単なコードなのですが、これが数十、数百になると、コードが寿限無化してしまい、
煩わしいばかりでなく、ミスもおこるし、修正も一苦労です。

いままで、我慢して使っていましたが、これではダメです。

連想配列のキーに、以上・未満の条件式が使えれば良いのですが、可能なのでしょう?
できない場合は、寿限無寿限無コードを使用しないで済む方法があったら、教えてください。

最悪の場合、寿限無コードの変化する部分を配列にして、同一番号で呼び出すようにして、ミスを減らすしかないのですが。

タークン
作成: 2024/05/30 (木) 18:02:06
最終更新: 2024/06/02 (日) 18:20:08
通報 ...
1
りんご 2024/05/30 (木) 18:21:07 935bc@0e907

 ごめん、この質問はMsAccess掲示板にあっているのかしら?hatenaさん、教えて下さい。
 連想配列などコードでごりごりデータベースをやっていた時代があって、画期的なMsAccessが登場したおかげでそんな事をやらなくていい時代になって、労働生産性が改善されたんじゃなかったっけー?

2
タークン 2024/05/30 (木) 19:21:12 7a0a1@2705a

x >= 63000 And x < 73000に対応できる、accessのデータ型をご存じでしたら、ご教授ください。
最大値と最小値を登録して検索させるというのであれば、寿限無地獄です。

3
タークン 2024/05/30 (木) 20:27:43 7a0a1@2705a

これの手がありました。
わずか、20行。
頭が悪いという事は、不幸です~~~~~。

    Min = Split("0,63000,73000,83000,93000,101000,107000,114000,122000,130000,138000,146000,155000,165000,175000,185000,195000,210000,230000,250000,270000,290000,310000,330000,350000,370000,395000,425000,455000,485000,515000,545000,575000,605000,635000,665000,695000,730000,770000,810000,855000,905000,955000,1005000,1055000,1115000,1175000,1235000,1295000,1355000", ",")
    mx = Split("63000,73000,83000,93000,101000,107000,114000,122000,130000,138000,146000,155000,165000,175000,185000,195000,210000,230000,250000,270000,290000,310000,330000,350000,370000,395000,425000,455000,485000,515000,545000,575000,605000,635000,665000,695000,730000,770000,810000,855.ooo,905000,955000,1005000,1055000,1115000,1175000,1235000,1295000,1355000,1355000", ",")
    gr1 = Split("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50", ",")
    std1 = Split("58000,68000,78000,88000,98000,104000,110000,118000,126000,134000,142000,150000,160000,170000,180000,190000,200000,220000,240000,260000,280000,300000,320000,340000,360000,380000,410000,440000,470000,500000,530000,560000,590000,620000,650000,680000,710000,750000,790000,830000,880000,930000,980000,1030000,1090000,1150000,1210000,1270000,1330000,1390000", ",")
    gr2 = Split("1,1,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32", ",")
    std2 = Split("88000,88000,88000,88000,98000,104000,110000,118000,126000,134000,142000,150000,160000,170000,180000,190000,200000,220000,240000,260000,280000,300000,320000,340000,360000,380000,410000,440000,470000,500000,530000,560000,590000,620000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000", ",")

    For i = 1 To 49
     If x >= Min(i) And mx(i) Then
         gr = gr1(i)
          std1 = std1(i)
           gr2 = gr2(i)
            std2 = std2(i)
             Exit For
         Else
           gr = gr1(50)
            std1 = std1(50)
             gr2 = gr2(50)
              std2 = std2(50)
      End If
    Next

4

連想配列のキーに、以上・未満の条件式が使えれば良いのですが、可能なのでしょう?

連想配列のキーは完全一致しか無理です。完全一致なので高速に検索できるのです。


    If x  < 63000 Then
        gr = 1
      Else
        If x >= 63000 And x < 73000 Then
            gr = 2
       Else
         If x >= 73000 And x < 83000 Then
             gr = 3
      End if

このコードなら、xが10000間隔でgrが1増えていくという規則性があるので、下記のようなコードで可能です。

    If x < 63000 Then
        gr = 1
    Else
        gr = (x - 63000) \ 10000 + 2
    End If

間隔が不規則であるなら、下記のようなテーブルを作成してそれを参照すればいいでしょう。

grx_low
10
263000
373000
485000
592000
6107000

x_lowには範囲の下限値を入力しておきます。
また、インデックスを設定しておくと高速に検索できます。
下記のコードでgrを取得できます。

    gr = DMax("gr","tbl1","x_low<=" & x)
6
タークン 2024/05/30 (木) 21:46:24 7a0a1@2705a

このように修正したら、正常になりました。
ご指摘の通り、配列のままでは使えませんでした。
実際には、PDFの表を変換したデータを使います。

とりあえず、税額表等のデータは、寿限無コードを使わなくて済むようになったので、
無駄な労力を使わなくて済むようになりました。

Dim x As Long
Dim y As Long
Dim z As Long

    Min = Split("0,63000,73000,83000,93000,101000,107000,114000,122000,130000,138000,146000,155000,165000,175000,185000,195000,210000,230000,250000,270000,290000,310000,330000,350000,370000,395000,425000,455000,485000,515000,545000,575000,605000,635000,665000,695000,730000,770000,810000,855000,905000,955000,1005000,1055000,1115000,1175000,1235000,1295000,1355000", ",")
    mx = Split("63000,73000,83000,93000,101000,107000,114000,122000,130000,138000,146000,155000,165000,175000,185000,195000,210000,230000,250000,270000,290000,310000,330000,350000,370000,395000,425000,455000,485000,515000,545000,575000,605000,635000,665000,695000,730000,770000,810000,855.ooo,905000,955000,1005000,1055000,1115000,1175000,1235000,1295000,1355000,1355000", ",")
    gr1 = Split("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50", ",")
    std1 = Split("58000,68000,78000,88000,98000,104000,110000,118000,126000,134000,142000,150000,160000,170000,180000,190000,200000,220000,240000,260000,280000,300000,320000,340000,360000,380000,410000,440000,470000,500000,530000,560000,590000,620000,650000,680000,710000,750000,790000,830000,880000,930000,980000,1030000,1090000,1150000,1210000,1270000,1330000,1390000", ",")
    gr2 = Split("1,1,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32", ",")
    std2 = Split("88000,88000,88000,88000,98000,104000,110000,118000,126000,134000,142000,150000,160000,170000,180000,190000,200000,220000,240000,260000,280000,300000,320000,340000,360000,380000,410000,440000,470000,500000,530000,560000,590000,620000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000,650000", ",")

    x = 70000

    For i = 0 To 48
    gr = ""
    y = Min(i)
    z = mx(i)
     If x >= Min(i) And x < mx(i) Then
         gr = gr1(i)
          std1 = std1(i)
           gr2 = gr2(i)
            std2 = std2(i)
             Exit For
      End If
    Next

    If gr = "" Then
        gr = gr1(49)
         std1 = std1(49)
          gr2 = gr2(49)
           std2 = std2(49)
     End If

7

PDFの表なら、もっといい方法はありそうですが、
後だしで、どんどん情報がかわっていくいつものパターンなので、
まあいいや。

8
タークン 2024/05/31 (金) 15:44:39 7a0a1@2705a

わずかな手抜きは止めて、2次配列に格納する事にしました。

9
hatena 2024/06/02 (日) 18:17:17 修正

ここはAccessに関する質疑応答、技術的な情報交換の場です。
それを踏まえて、他の閲覧者や後から検索で訪問した人にとって、意味のある情報になるように、下記のような要件に対してAccessでどのように解決するかという観点で、回答をおいておきます。


  • PDF内に表データがある。
  • それをAccessに取り込んで、有効活用したい。
  • 表データは、下記のようなものとする。
下限値上限値gr1std1gr2std2
063000158000188000
6300073000268000188000
7300083000378000188000
8300093000488000188000
93000101000598000298000
10100010700061040003104000
10700011400071100004110000

PDFから表データを取り込む

WordでPDFファイルを開きます。
欲しい表部分をコピーしてエクセルのシートに貼り付けます。
これをAccessにインポートします。
これで、pdfの表データをAccessのテーブルとして取り込めます。
これは1回のみの作業なのでVBAにするまでもないでしょう。

VBAで自動化したい場合は、下記等を参考に。
【Excel/VBA】PDFやWordから表データだけを抽出するマクロ | hamalabo


キー値をもとに、下限値と上限値の範囲に合致するデータをとりだす。

取り込んだテーブル名はTbl1とする。
[条件値]と[下限値]フィールドにインデックスを設定する。

    Const cSQL = ""SELECT * FROM Tbl1 WHERE 下限値<=[x] AND 上限値>[x];"
    Dim rs As DAO.Recordset, x As Long
    x = Val(InputBox("数値を入力"))
    Set rs = CurrentDB.OpenRecordset(Replace(cSQL,"[x]",x))
    If rs.EOF Then
        MsgBox "該当するデータはありません。"
    Else
        MsgBox "gr1: " & rs!gr1 & vbCrLf & _
               "std1: " & rs!std1 & vbCrLf & _
               "gr2: " & rs!gr2 & vbCrLf & _
               "std2: " & rs!std2 
    End If