Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


159 / 2272 ツリー ←次へ | 前へ→

【12778】所得税の算出 ppp3 15/3/26(木) 19:53 質問[未読]
【12779】Re:所得税の算出 かるびの 15/3/27(金) 1:23 回答[未読]
【12780】Re:所得税の算出 ppp3 15/3/27(金) 21:31 質問[未読]
【12781】Re:所得税の算出 かるびの 15/3/28(土) 1:21 回答[未読]
【12784】Re:所得税の算出 かるびの 15/3/29(日) 2:47 発言[未読]
【12785】Re:所得税の算出 ppp3 15/3/29(日) 22:39 質問[未読]
【12786】Re:所得税の算出 かるびの 15/3/30(月) 2:18 回答[未読]
【12788】Re:所得税の算出 ppp3 15/3/30(月) 22:55 質問[未読]
【12789】Re:所得税の算出 かるびの 15/3/31(火) 1:50 回答[未読]
【12791】Re:所得税の算出 pp3 15/3/31(火) 8:15 質問[未読]
【12792】Re:所得税の算出 かるびの 15/3/31(火) 13:46 回答[未読]

【12778】所得税の算出
質問  ppp3  - 15/3/26(木) 19:53 -

引用なし
パスワード
   お世話になります
所得税の算出に困ってます
以下のテーブルから給料明細クエリの所得税
にどのような式を組み込めばよいですか?

従事者テーブル
氏名    雇用区分    控除後金額    扶養人数
太郎    社員      392050        1
次郎    社員      389100        4
三郎    非社員     380001        1
五郎    正社員     0           4

所得率表テーブル
以上    未満    0人    1人    2人    3人    4人    5人    6人    7人
380,000  383,000  15,040  11,800   8,570    6,820  5,200    3,580  1,970    350
383,000  386,000  15,280  12,050   8,810    6,940  5,320    3,710  2,090    470
386,000  389,000  15,530  12,290   9,060    7,070  5,440    3,830  2,220    590
389,000  392,000  15,770  12,540   9,300    7,190  5,560    3,950  2,340    710
392,000  395,000  16,020  12,780   9,550    7,310  5,690    4,070  2,460    840


給料明細クエリ
氏名    雇用区分    控除後金額    扶養人数       所得税
太郎    社員      392050        1        12780
次郎    社員      389100        4        5560
三郎    非社員     380001        1        0
五郎    正社員     0           4        0

access 2007
ご教授頂ければ幸いです

【12779】Re:所得税の算出
回答  かるびの  - 15/3/27(金) 1:23 -

引用なし
パスワード
   >給料明細クエリの所得税
>にどのような式を組み込めばよいですか?

 アクセスには、エクセルにおけるHLookUp関数と同様の働きをする関数はありません。

 また、発想の方向性が少しズレていると思います。
 「式を組み込む」という発想がアクセス的ではありません。
 エクセルでは、集計ないし計算結果を表示するセルに
どのような式ないし関数を設定するかが勝負となりますが、
アクセスでは、どのテーブルとどのテーブルとを、どのように結合させるか
という発想が中心になります。


 そこで、給料明細クエリをどのように作るかですが、その前提として、
所得率表テーブルのテーブル構成がまずいと思います。
 
 エクセルでは、表が所与のものとしてあって、
これをどのように集計・計算していくかという視点から、
関数ないし計算式を考えていきます。
 これに対し、アクセスでは、集計・計算しやすいようにテーブルを作ります。

 
 アクセスは、条件に合うレコードを見つけることは大得意ですが、
条件に合うフィールドを見つけるということはできません。
 扶養人数が3である場合に、
所得率表テーブルの「3人」フィールドを見つけてくるということ
ができないのです
(なお、VBAを駆使すればできないことはありませんが、パフォーマンスは悪くなります)。

 そのため、所得率表テーブルは次のような構成にします。

以上    未満  扶養人数 所得税額
380,000  383,000     0  15,040
380,000  383,000     1  11,800
380,000  383,000     2   8,570
        ・・・・・・
383,000  386,000     0  15,280
383,000  386,000     1  12,050
383,000  386,000     2   8,810

 これに対し、テーブルが見づらくなるという批判が出てくるだろうと思います。
 しかし、テーブルは、レコードを格納するたのオブジェクトであって、
レコードを表示させるためのオブジェクトではないので、
人間にとっての見やすさを考慮する必要はありません。
 むしろ、コンピュータにとっての使いやすさこそを優先させたテーブル構成
としなければなりません。
 また、扶養人数が横に展開していくような形でレコードを表示したいなら、
クロス集計クエリを使えば、そのような形でのレコード表示が可能です。
 

 そして、給料明細クエリにおける結合条件を
     従事者テーブル.控除後金額 >= 所得率表テーブル.以上
   AND 従事者テーブル.控除後金額 < 所得率表テーブル.以下
   AND 従事者テーブル.扶養人数 = 所得率表テーブル.扶養人数
とします。
 不等号を使った結合条件は、クエリ・デザイナでは作れなかったと思います。
なので、給料明細クエリSQLビューを使い、
SQL文を記述して作成してください。


 なお、結合条件に不等号を使うと、クエリが極端に遅くなるという印象です。
 なので、できたら、上記の結合条件は避けた方が無難ではないかと思います。


 これに関し、国税庁のホームページ中に

ht tp://www.nta.go.jp/shiraberu/ippanjoho/pamph/gensen/shikata2015
/pdf/06.pdf

というページがあります。PDFのページですが、その14ページに
「(平成27年分の年末調整のための算出所得税額の速算表)」という表が
あります。
 この表による計算をユーザー関数化したら、
所得率表テーブルなど不要になると思います。

 上述のアクセスとエクセルの対比のところに記載したことと
ちょっと矛盾しますが、
このようなユーザー関数化も一法ではないかなと思います。

【12780】Re:所得税の算出
質問  ppp3  - 15/3/27(金) 21:31 -

引用なし
パスワード
       お返事有難う御座います

> なお、結合条件に不等号を使うと、クエリが極端に遅くなるという印象です。
> なので、できたら、上記の結合条件は避けた方が無難ではないかと思います。

以下を参考に実装した所表示までに1分30秒程掛かりました。
結合をしてもほぼ同じような感じがします

www.税務経理.com/accessで源泉所得税を計算1./


源泉税額: Int(DLookUp(“源泉税額”,”源泉徴収税額表”,”[以上]<=” & [給料] & “” & ” and ” & “[未満]>” & [給料] & “” & ” and ” & “[扶養親族]=” & [扶養] & “”))/1

> これに関し、国税庁のホームページ中に
>
>ht tp://www.nta.go.jp/shiraberu/ippanjoho/pamph/gensen/shikata2015
>/pdf/06.pdf
>
>というページがあります。PDFのページですが、その14ページに
>「(平成27年分の年末調整のための算出所得税額の速算表)」という表が
>あります。
> この表による計算をユーザー関数化したら、
>所得率表テーブルなど不要になると思います。
>
> 上述のアクセスとエクセルの対比のところに記載したことと
>ちょっと矛盾しますが、
>このようなユーザー関数化も一法ではないかなと思います。

具体的な方法はどの様にすればよろしいでしょうか?

【12781】Re:所得税の算出
回答  かるびの  - 15/3/28(土) 1:21 -

引用なし
パスワード
   >> これに関し、国税庁のホームページ中に
>>
>>ht tp://www.nta.go.jp/shiraberu/ippanjoho/pamph/gensen/shikata2015
>>/pdf/06.pdf
>>
>>というページがあります。PDFのページですが、その14ページに
>>「(平成27年分の年末調整のための算出所得税額の速算表)」という表が
>>あります。

とレスしましたが、上記は、年間の税額を計算する方法なので、ちょっと違いますね。

 むしろこっちの方ですね。

月額表の甲欄を適用する給与等に対する源泉徴収税額の電算機計算の特例
ht tp://www.nta.go.jp/shiraberu/ippanjoho/pamph/gensen/zeigakuhyo2014/data/05.pdf 


 ただ、
ht tp://www.nta.go.jp/shiraberu/ippanjoho/pamph/gensen/zeigakuhyo2014
/data/01.pdf
を見ると、税額表による源泉額と、電算機計算の特例による源泉額とでは、
若干の差が出るみたいです。


>>このようなユーザー関数化も一法ではないかなと思います。
>
>具体的な方法はどの様にすればよろしいでしょうか?

 このユーザー定義関数は、クエリからアクセスできる必要があるので、
標準モジュールに書きます。
 引数を、社会保険料等を控除した後の給与等の金額
及び控除対象扶養親族の数とし、返り値を源泉所得税額とします。


 触りのところだけ書くと、 

Function FnGensenGaku(lngSalary As Long,bytFuyo As Byte) As Long

End Function

となります。

 Function で始まる行と、End Function の行の間に
コードを書いていくことになります。
 コードの組み立ては、上記の電算機計算の特例に記載された手順を
丹念になぞっていけばいいと思います。
 なお、私からコードを示すつもりはありません。


 今回ちょっと調べた結果、
税額表による源泉額と電算機計算の特例による源泉額とでは、
差が出ることがわかったので、
やっぱり税額表を使う方法による方がいいのかなと思い始めています。

 その方法ですが、まず、税額表から「未満」フィールドを削除したテーブルを
用意します。

以上   扶養人数 所得税額
380,000     0  15,040
380,000     1  11,800
380,000     2   8,570
        ・・・・・・
383,000     0  15,280
383,000     1  12,050
383,000     2   8,810

 次に、社会保険料等控除後金額から税額表の「以上」フィールドの値を求める
ユーザー定義関数を作ります。
 すなわち、控除金額が392,050円の人は、
税額表において控除金額が392,000円以上395,000円未満の行に該当するので、
392,000円という値を返し、
控除金額が394,000円の人は、392,000円という値を返し、
控除金額が397,000円の人は、395,000円という値を返す
という処理をする関数を作ります。

 その上で、従事者テーブルにプラスして
この関数を使った演算フィールド(フィールド名「基準額」)
を持つクエリを作り(クエリ名「Q一次」)、
Q一次と税額表とを、「基準額」フィールドと「以上」フィールド、
及び「扶養人数」フィールドで結合させたクエリを作ります
(クエリ名「Q二次」)。

 このようにすれば、結合条件に不等号を使わずに済むので、
いくらかはクエリが速くなるのではないかと思います。
 ただし、試したわけではないので、本当に速くなるかどうかは未知数です。


 これでもまだ遅いようであれば、
Q一次と税額表との結合は1フィールドだけにして、
もう片方の結合条件は、抽出条件とするという方法を試すことになりそうです。

【12784】Re:所得税の算出
発言  かるびの  - 15/3/29(日) 2:47 -

引用なし
パスワード
   > 次に、社会保険料等控除後金額から税額表の「以上」フィールドの値を求める
>ユーザー定義関数を作ります。

 興味が湧いたので、このユーザー定義関数を考えてみました。

Function FnIjogaku(lngKojogo As Long) As Long
  Dim lngHasu As Long
  Dim lngRslt As Long
  
  If lngKojogo < 1010000 Then
    Select Case lngKojogo
      Case Is < 99000
        lngHasu = lngKojogo Mod 1000
    
      Case Is < 221000
        lngHasu = (lngKojogo - 99000) Mod 2000
  
      Case Is < 1010000
        lngHasu = (lngKojogo - 221000) Mod 3000
    End Select

    lngRslt = lngKojogo - lngHasu
  Else
  
  End If
End Function

 補足すると、引数のlngKojogoは、社会保険料等控除後の給料額です。

 以上と未満の幅は、
控除後給料額が   0〜  99,000のとき、1000円幅、
        99,000〜 221,000のとき、2000円幅、
       221,000〜1,010,000のとき、3000円幅
ですが、変数lngHasuは、この幅に満たない端数のことです。

 社会保険料等控除後の給料額からこの端数を引けば、
所得率表テーブルの「以上」フィールドの値になるはずです。

 返り値は、所得率表テーブルの「以上」フィールドの数値です。

 Else以下、つまり、社会保険料控除後の給料額が101万円以上の場合も
書こうかと思ったのですが、力尽きました。

【12785】Re:所得税の算出
質問  ppp3  - 15/3/29(日) 22:39 -

引用なし
パスワード
   ▼かるびの さん:
>> 次に、社会保険料等控除後金額から税額表の「以上」フィールドの値を求める
>>ユーザー定義関数を作ります。
>
> 興味が湧いたので、このユーザー定義関数を考えてみました。
>
>Function FnIjogaku(lngKojogo As Long) As Long
>  Dim lngHasu As Long
>  Dim lngRslt As Long
>  
>  If lngKojogo < 1010000 Then
>    Select Case lngKojogo
>      Case Is < 99000
>        lngHasu = lngKojogo Mod 1000
>    
>      Case Is < 221000
>        lngHasu = (lngKojogo - 99000) Mod 2000
>  
>      Case Is < 1010000
>        lngHasu = (lngKojogo - 221000) Mod 3000
>    End Select
>
>    lngRslt = lngKojogo - lngHasu
>  Else
>  
>  End If
>End Function
>
> 補足すると、引数のlngKojogoは、社会保険料等控除後の給料額です。
>
> 以上と未満の幅は、
>控除後給料額が   0〜  99,000のとき、1000円幅、
>        99,000〜 221,000のとき、2000円幅、
>       221,000〜1,010,000のとき、3000円幅
>ですが、変数lngHasuは、この幅に満たない端数のことです。
>
> 社会保険料等控除後の給料額からこの端数を引けば、
>所得率表テーブルの「以上」フィールドの値になるはずです。
>
> 返り値は、所得率表テーブルの「以上」フィールドの数値です。
>
> Else以下、つまり、社会保険料控除後の給料額が101万円以上の場合も
>書こうかと思ったのですが、力尽きました。

お返事有難うございます
貴重なソース有難う御座います
やはり基本ベースは所得率表テーブルだと思っております

年1度の更新時期に所得率表テーブルを使用者が変更した時に
対応できるようにしたい為です。

どうにかなりませんか?

【12786】Re:所得税の算出
回答  かるびの  - 15/3/30(月) 2:18 -

引用なし
パスワード
   >やはり基本ベースは所得率表テーブルだと思っております
>
>年1度の更新時期に所得率表テーブルを使用者が変更した時に
>対応できるようにしたい為です。
>
>どうにかなりませんか?

 私が12481のレスで提示した

以上   扶養人数 所得税額
380,000     0  15,040
380,000     1  11,800
380,000     2   8,570
        ・・・・・・
383,000     0  15,280
383,000     1  12,050
383,000     2   8,810

というテーブルを使うことは、リレーショナルベータベースを使う限り、
避けられないと思います。

 上例のようなテーブルを用意することは、それほど手間がかかることでは
ありません。
 所得率表テーブルから追加クエリでレコードを追加するだけです。

 その追加クエリですが、
所得率表テーブルの「以上」フィールドと「0人」ないし「7人」フィールドが
ともに長整数型だとし、
かつ、上例のようなテーブルのテーブル名が「T税額表」だとし、
そのテーブル構成が
   ID    オートナンバー(主キー)
   以上   長整数型
   扶養人数 バイト型
   所得税額 長整数型
だとして、次のようなものになります。

INSERT INTO T税額表
(以上,扶養人数,税額)
SELECT 以上,0 AS 扶養人数,[0人] AS 税額
FROM 所得率表テーブル
UNION ALL 
SELECT 以上,1 AS 扶養人数,[1人] AS 税額
FROM 所得率表テーブル
UNION ALL 
SELECT 以上,2 AS 扶養人数,[2人] AS 税額
FROM 所得率表テーブル
   ・・・・・
UNION ALL 
SELECT 以上,7 AS 扶養人数,[7人] AS 税額
FROM 所得率表テーブル


 一つ気になるのは、所得率表テーブルの「0人」ないし「7人」フィールドの
フィールド名です。
 フィールドの命名規則として、数字で始まるフィールド名はNGですから、
これが原因で何らかのエラーが生じ、追加クエリが実行できないかもしれません。
 このエラーは、追加クエリだから出るというのではなく、
単なる選択クエリでも生じる可能性があります。
 所得率表テーブルの「0人」ないし「7人」フィールドは、
フィールド名を変えておいた方が無難だと思います。


 どうしても、上例のようなテーブルを作りたくないならば、
ユニオンクエリを使うという方法が考えられます。
 所得率表テーブルから上例のようなレコードを返すクエリを
ユニオンクエリで作るという方法です。

 もっとも、上例のようなテーブルを使う場合に比べて、
ユニオンクエリの処理が必要になる分、遅くなるのがデメリットです。

 ユニオンクエリの作り方ですが、クエリデザイナでは作れないので、
SQLビューで作ります。
 SQLビューに次のように入力してください。

SELECT 以上,0 AS 扶養人数,[0人] AS 税額
FROM 所得率表テーブル
UNION ALL 
SELECT 以上,1 AS 扶養人数,[1人] AS 税額
FROM 所得率表テーブル
   ・・・・・
UNION ALL 
SELECT 以上,7 AS 扶養人数,[7人] AS 税額
FROM 所得率表テーブル

 なお、上記の「・・・・・」の部分は、
私がSQL文を逐一書くのが面倒なため、省略したものですので、
実際にSQLビューに書くときは、省略せずに書いてください。


 T税額表を新規に作るにせよ、それをユニオンクエリで代用するにせよ、
あとの手順は、私の12781のレスの
>> その上で、従事者テーブルにプラスして
>>この関数を使った演算フィールド(フィールド名「基準額」)
>>を持つクエリを作り(クエリ名「Q一次」)、
>>Q一次と税額表とを、「基準額」フィールドと「以上」フィールド、
>>及び「扶養人数」フィールドで結合させたクエリを作ります
>>(クエリ名「Q二次」)。
のとおりです。

【12788】Re:所得税の算出
質問  ppp3  - 15/3/30(月) 22:55 -

引用なし
パスワード
   お返事有難うございます
誘導頂いたUNIONクエリまで出来ました!
でもそこから先が何度読み返しても分かりません!

> その上で、従事者テーブルにプラスして
>この関数を使った演算フィールド(フィールド名「基準額」)
>を持つクエリを作り(クエリ名「Q一次」)、
>Q一次と税額表とを、「基準額」フィールドと「以上」フィールド、
>及び「扶養人数」フィールドで結合させたクエリを作ります
>(クエリ名「Q二次」)。
>
> このようにすれば、結合条件に不等号を使わずに済むので、
>いくらかはクエリが速くなるのではないかと思います。
> ただし、試したわけではないので、本当に速くなるかどうかは未知数です。
>
>
> これでもまだ遅いようであれば、
>Q一次と税額表との結合は1フィールドだけにして、
>もう片方の結合条件は、抽出条件とするという方法を試すことになりそうです。

【12789】Re:所得税の算出
回答  かるびの  - 15/3/31(火) 1:50 -

引用なし
パスワード
   >誘導頂いたUNIONクエリまで出来ました!

 ユニオンクエリで行こうということですか。
 間違った方向に進もうとしているような気がします。

 間違った方向に進んでも、例えば、給料明細クエリを表示させるだけにとどまっている限りは、
そう大きな影響はないでしょうが、
さらなる機能を付加したいと思ったときに、正しい方向に進んだ場合に比べて、
膨大な手間を要することになります。
 つまり、正しい方向に進んでいれば、クエリを1つ作るだけで済むところを、
間違った方向に進んでしまうと、それを全てVBAで処理するということになってしまいます。
 そして、そうなったときに、掲示板で質問しても、
「テーブルをちゃんと作れ」というアドヴァイスしか返ってこず、
独力でVBAのコードを完成させることになってしまいます。


>でもそこから先が何度読み返しても分かりません!

 12781のレスの繰り返しでしかありませんが、
クエリは2つ作ります。1つがQ一次クエリで、もう1つがQ二次クエリです。

 Q一次クエリは、従事者テーブルに演算フィールドを設けるだけです。
 演算フィールドには、12784のレスで紹介したFnIjogaku関数を仕込みます。
 なお、FnIjogaku関数は、頭の中で考えただけであり、試してはいないので、
修正をする必要があるかもしれません。
 この演算フィールドの名前は、何でもいいのですが、
「基準額」という名前だとして説明を続けます。


 Q二次クエリでは、Q一次クエリとユニオンクエリとを結合させます。

 この結合フィールドをどうするかちょっと考えどころです。
 12781のレスでは、結合フィールドは2つ、つまり、
1つが「基準額」フィールドと「以上」フィールド、
もう1つが「扶養人数」フィールドと「扶養人数フィールド」
とすることを提案したのですが、
結合フィールドは1つだけにして、他方の結合条件は、抽出条件とした方が
クエリが速いのではないだろうかとも思っています。
 結合フィールドを2フィールドにした方が速いのか、1フィールドだけにした方が速いのかは、
実際に両方のクエリを作って、実験してみるよりないですね。


 それから大事なことですが、
Q二次クエリは、ユニオンクエリをベースにしたクエリなので、
更新不可のクエリです。
 つまり、Q二次クエリ上で新規レコードを入力することはできませんし、
既存レコードの修正をすることもできません。
 レコードを表示するだけです。

【12791】Re:所得税の算出
質問  pp3  - 15/3/31(火) 8:15 -

引用なし
パスワード
   > 12781のレスの繰り返しでしかありませんが、
>クエリは2つ作ります。1つがQ一次クエリで、もう1つがQ二次クエリです。
>
> Q一次クエリは、従事者テーブルに演算フィールドを設けるだけです。
> 演算フィールドには、12784のレスで紹介したFnIjogaku関数を仕込みます。
> なお、FnIjogaku関数は、頭の中で考えただけであり、試してはいないので、
>修正をする必要があるかもしれません。
> この演算フィールドの名前は、何でもいいのですが、
>「基準額」という名前だとして説明を続けます。
おはようございます
FnIjogaku関数のを仕込むには、具体的にどうすればよいですか?
しつこくてすみません

【12792】Re:所得税の算出
回答  かるびの  - 15/3/31(火) 13:46 -

引用なし
パスワード
   >FnIjogaku関数のを仕込むには、具体的にどうすればよいですか?

 つまづいているのは、やはりそこでしたか。

 次のページが参考になると思います。

Accessむかむか
クエリで自作関数を使用する
ht tp://sanryu.net/acc/tips/tips132.htm


T's Ware 
オリジナル関数をクエリーで使う方法 
ht tp://www.tsware.jp/tips/tips_202.htm  


 FnIjogaku関数を使う場合、関数の引数と、引数として使うフィールドのデータ型を
合わせるようにしてください。
 そうでないと、データ型が違う旨のエラーになります。 

159 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078190
(SS)C-BOARD v3.8 is Free