Excel VBA質問箱 IV

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

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


2869 / 13646 ツリー ←次へ | 前へ→

【65516】User_formの修復について(至急!!!) 八家九僧陀 10/6/1(火) 17:52 質問[未読]
【65517】Re:User_formの修復について(至急!!!) Yuki 10/6/1(火) 19:20 発言[未読]
【65518】Re:User_formの修復について(至急!!!) よろずや 10/6/1(火) 19:43 回答[未読]
【65519】Re:User_formの修復について(至急!!!) 247b 10/6/1(火) 21:08 発言[未読]
【65520】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 0:32 質問[未読]
【65521】Re:User_formの修復について(至急!!!) Hirofumi 10/6/2(水) 7:37 発言[未読]
【65522】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 9:14 発言[未読]
【65523】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 9:38 発言[未読]
【65524】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 13:12 質問[未読]
【65525】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 14:41 発言[未読]
【65528】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 15:47 質問[未読]
【65533】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 16:53 発言[未読]
【65535】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 19:08 質問[未読]
【65536】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 20:50 発言[未読]
【65537】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 22:06 質問[未読]
【65538】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 22:39 発言[未読]
【65539】Re:User_formの修復について(至急!!!) 247b 10/6/2(水) 22:45 発言[未読]
【65540】Re:User_formの修復について(至急!!!) 八家九僧陀 10/6/2(水) 23:42 質問[未読]
【65541】Re:User_formの修復について(至急!!!) 247b 10/6/3(木) 0:19 発言[未読]

【65516】User_formの修復について(至急!!!)
質問  八家九僧陀  - 10/6/1(火) 17:52 -

引用なし
パスワード
   今まで重たいながらも何とか動いていたUser_Formが、あるcomboboxに係るコードを追加したら、「実行時エラー380 Valueプロパティを設定できません。プロパティの値が不正です。」とのエラーメッセージが表示され動かなくなりました。
「ヘルプ」をクリックしても「このトピックは存在しません。製造元に・・・・(129)」と表示されます。(excel97を使用しています。)

以下に1.しようとしたこと と、2.コードを記述しますので、対処方法をご教示ください。

1.毎月の月給処理用のUser_Formです。
 A列〜CR列、80行(名、行は毎月若干の増減があります)のリストデータ形式のsheet("支給台帳")にUser_Formを使って入力しています。5月分はうまく入力できました。
 が、試行してみて、基本給や通勤費、社会保険料や所得税の扶養家族数等、毎月毎月変動のないものは、別シート(”給与マスター”)に登録させておいて、キーとなる社員IDをcomboboxで選択して、text基本給やtext通勤費等に取り込めるように改良しようと、以前この質問箱で回答いただいたComboboxの複数列表示と他のtextへの取り込みのVBAを盗用して加筆しました。加筆したとたんに動かなくなりました。

2.以下にコードを記述しますので、改良点、対処法をご教示ください。
(なお手書きのため、大文字、小文字等の混在をお許しください。)


Option Explicit

Dim TBL(1 to 90) as Control
Dim データ範囲 as range
Dim r as Range ←今回の追加

Private sub Userform_initialize()

'///////// ココから新規追加(質問箱から盗用)
Set r = worksheets("仮マスター").Range("A1").CurrentRegion
Set r = intersect(r,r.Offset(1))

With Me.Combo社員ID
  .rowsource = r.address(external:=True)
  .ColumnHeads = True
  .TextColumn = 1
  .BoundColumn = 2
  .ColumnCount = 2
  .ColumnWidths = "40:60"
End with
'////// ココまで

Spin移動.Max=レコード数取得 + 1

set TBL(1) = text支給年月日
set TBL(2) = text種別
set TBL(3) = Combo社員ID ←このIDにより以下の約20個のtextboxに値を取得
set TBL(4) = text氏名


set TBL(96) = text差引支給額 ’Combo社員ID以外は全てtextBoxです

Set データ範囲 = worksheets("支給台帳").Range("A1").currentRegion

if データ範囲.Rows.Count = 1 then
Else
データ表示 2
End If
End Sub

Pubulic Finction レコード数取得() as integer
レコード数取得 = worksheets("支給台帳").Range("A1").currentRegion.Rows.Count -1
End Function

Public Sub データ表示(行数 as integer)
Dim Cnt as integer,vntData as Variant
vntData = worksheets("支給台帳").Range("A1").currentRegion.Rows(行数).value
For Cnt = 1 to 96 Step 1
TBL(Cnt) = vntData(1,Cnt) ←エラーメッセージのとき、ここが黄色に反転
Next
Textレコード.value = Spin移動.value -1 &"/"&レコード数取得
End Sub

Private Sub Spin移動_change()
if データ範囲.Rows.Count<> 1 then
データ表示(Spin移動.Value)
End if
End sub

Private Sub button追加_Click()
Dim addrow As integer
addrow= worksheets("支給台帳").Range("A1").currentRegion

データ書き込み (addrow)
Set データ範囲 = worksheets("支給台帳").range("A1").CurrentRegion
Spin移動.Max = データ範囲.Rows.Count
Spin移動.value = データ範囲.Rows.Count
データ表示 (addrow)
End Sub

Public Sub データ書き込み(行数 as integer)
Dim Cnt As integer,vntData() as Variant
Application.screenupdating = false
Redim vntData(1 to 1,1 to96)
For Cnt = 1 to 96
vntData(1,cnt)=TBL(cnt).value
Next
worksheets("支給台帳").Range("A1").currentRegion.Rows(行数).value = vntData
Application.screenupdating = true
End Sub

Public Sub button更新_click()
データ書き込み (Spin移動.value)
End Sub

private Sub button削除_click()
データ範囲.Rows (Spin移動.value).Delete
データ表示 (Spin移動.value)
Set データ範囲 =worksheets("支給台帳").Range("A1").CurrentRegion
Spin移動.Max = データ範囲.Rows.Count
End sub

private Sub button終了_click()

activeworkbook.Save
unload me

End sub
'////////////////////////// ココから新規追加(質問箱から盗用)
Private sub Combo社員ID_Change()
Application.screenupdating = False
  With Me.Combo社員ID
  if .ListIndex < then Exit Sub
  Combo社員ID.value = .List(.ListIndex, 0)
  Text氏名.value = .List(.ListIndex, 1)
  Text所属.value = .List(.ListIndex, 2)
   ・
   ・
   ・
  Text標準報酬月額.value = .List(.ListIndex, 22)
  Text市県民税.value = .List(.ListIndex, 23)
End With
set r = Noting
Application.screenupdating = True
End Sub

長々と記述してしましましたが、以上がUserForm上の、追加、更新、削除、終了のcommandbuttonと新規追加したCombo社員IDに係るコードです。
まだまだ続くのですが、以下は各textbox間で、入力した数値により、afterupdateで、それぞれ時間外手当や各種手当て、合計、社会保険料算出、源泉徴収税計算のVBAを記述しています。

エラー時に黄色に反転する"TBL(Cnt) = vntData(1,Cnt)"のコードとCombo社員IDから取得する値(value)との整合性がとれていないためでしょうか?
なんとか基本的(固定的)項目は、給与マスターの値をCombo社員IDから取得したID(数値データ)で、Vlookup的に取得できればと考えています。
ご教示お願いします。

あと欲張って申し訳ありませんが、うまく入力できていたときも、User_Formの表示場所を移動すると幾重もの影?が画面に残ります。処理が重いからではと素人判断しているのですが、もっと早くなるコードはあるでしょうか?

【65517】Re:User_formの修復について(至急!!!...
発言  Yuki  - 10/6/1(火) 19:20 -

引用なし
パスワード
   ▼八家九僧陀 さん:
気が付いた所だけ。

>Public Sub データ表示(行数 As Integer)
>Dim Cnt As Integer, vntData As Variant
>vntData = Worksheets("支給台帳").Range("A1").CurrentRegion.Rows(行数).Value
>For Cnt = 1 To 96 Step 1
>TBL(Cnt) = vntData(1, Cnt) ' ←エラーメッセージのとき、ここが黄色に反転
>Next
>Textレコード.Value = Spin移動.Value - 1 & "/" & レコード数取得
>End Sub



Dim Cnt As Integer, vntData As Variant
' CurrentRegion.Rows(行数)は 96桁 あるのですか?
vntData = Worksheets(1).Range("A1").CurrentRegion.Rows(行数).Value
For Cnt = 1 To 96 Step 1
' Dim TBL(1 To 90) As Control と定義してあるのに 96 迄回している
TBL(Cnt) = vntData(1, Cnt) ' ←エラーメッセージのとき、ここが黄色に反転
Next

【65518】Re:User_formの修復について(至急!!!...
回答  よろずや  - 10/6/1(火) 19:43 -

引用なし
パスワード
   全体的に無駄が多いです。
そのため、ソースが異常に大きくなっているのでは。
1つのモジュールに書けるコードの量には制限があります。

画面更新を停止したまま途中でプログラムを終了すると、
画面表示がおかしなことになります。

【65519】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/1(火) 21:08 -

引用なし
パスワード
   こんばんわ

>'////////////////////////// ココから新規追加(質問箱から盗用)
>Private sub Combo社員ID_Change()
>Application.screenupdating = False
>  With Me.Combo社員ID
>  if .ListIndex < then Exit Sub
>  Combo社員ID.value = .List(.ListIndex, 0)
>  Text氏名.value = .List(.ListIndex, 1)
>  Text所属.value = .List(.ListIndex, 2)
>   ・
>   ・
>   ・
>  Text標準報酬月額.value = .List(.ListIndex, 22)
>  Text市県民税.value = .List(.ListIndex, 23)
>End With
>set r = Noting
>Application.screenupdating = True
>End Sub

エラーの内容と修正箇所から推測するに、上記のテキストボックスのValueプロパティへの値設定箇所のいずれかで問題が発生していることが考えられます。

・考えられることとしては、Combo社員ID.Rowsourceに指定している範囲と、上記にある、.List(.ListIndex,23)のような記述で指定している範囲が合致しているかどうか再確認してください。
ColumnCountプロパティに2を指定しているのに、Listプロパティで列を23まで指定しているのは合致しないように思うんですが。どうなんでしょう。
・エラーメッセージが表示されたときに「デバッグ」ボタンを押して、どのステップで止まっているか確認してみてください。

【65520】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 0:32 -

引用なし
パスワード
   ▼247b さん:yukiさん、よろずやさん、ありがとうございます。

>Dim TBL(1 To 90) As Control と定義してあるのに 96 迄回している

すみません。手書きでしたので単なる誤記で、「1 to 96」です。


>
>>'////////////////////////// ココから新規追加(質問箱から盗用)
>>Private sub Combo社員ID_Change()
>>Application.screenupdating = False
>>  With Me.Combo社員ID
>>  if .ListIndex < then Exit Sub
>>  Combo社員ID.value = .List(.ListIndex, 0)
>>  Text氏名.value = .List(.ListIndex, 1)
>>  Text所属.value = .List(.ListIndex, 2)
>>   ・
>>   ・
>>   ・
>>  Text標準報酬月額.value = .List(.ListIndex, 22)
>>  Text市県民税.value = .List(.ListIndex, 23)
>>End With
>>set r = Noting
>>Application.screenupdating = True
>>End Sub
>
>エラーの内容と修正箇所から推測するに、上記のテキストボックスのValueプロパティへの値設定箇所のいずれかで問題が発生していることが考えられます。

この部分を含むCombo社員ID関連のコード部分に「’」をつけてコメント扱い(無効)にすると、いままでのどおりの動きをします。

>・考えられることとしては、Combo社員ID.Rowsourceに指定している範囲と、上記にある、.List(.ListIndex,23)のような記述で指定している範囲が合致しているかどうか再確認してください。

Combo社員ID.Rowsourceは、別bookの給与マスター(A列〜W列=23列、80行程度(毎月若干変動)のリスト)をrange("A1").currentregionでselectして、このbookのSheets("仮マスター").range("A1")にcopyして,Dim r as rangeとしています。


>ColumnCountプロパティに2を指定しているのに、Listプロパティで列を23まで指定しているのは合致しないように思うんですが。どうなんでしょう。

Combo社員IDには、「社員ID」と「氏名」の2列を表示して選択させるようにしています。その選択した行の各列の値をListプロパティで各textboxに代入しようとしています。

>・エラーメッセージが表示されたときに「デバッグ」ボタンを押して、どのステップで止まっているか確認してみてください。

TBL(Cnt) = vntData(1,Cnt) ←エラーメッセージのとき、ここが黄色に反転しています。

>全体的に無駄が多いです。
>そのため、ソースが異常に大きくなっているのでは。
>1つのモジュールに書けるコードの量には制限があります。

極力処理が重たくならない、処理速度も速くしたいと思っています。
具体的にどの部分、コードが、「無駄」なのかご教示願いますか?

切羽詰っています。何とかお助けを〜〜〜〜〜〜!!
comboboxからのListプロパティでの取得方法のほかに、よい方法はないでしょうか?

【65521】Re:User_formの修復について(至急!!!...
発言  Hirofumi  - 10/6/2(水) 7:37 -

引用なし
パスワード
   先ずは、単純な構文の間違いを直してからでは?


Public Sub データ表示(行数 As Integer)

  Dim Cnt As Integer, vntData As Variant
  
  vntData = Worksheets("支給台帳").Range("A1").CurrentRegion.Rows(行数).Value
  
  For Cnt = 1 To 96 Step 1
'    TBL(Cnt) = vntData(1, Cnt) '←エラーメッセージのとき、ここが黄色に反転
    TBL(Cnt).Value = vntData(1, Cnt) '←エラーメッセージのとき、ここが黄色に反転
  Next
  
  Textレコード.Value = Spin移動.Value - 1 & "/" & レコード数取得
  
End Sub

Control型の変数に値を代入している?


'////////////////////////// ココから新規追加(質問箱から盗用)
Private Sub Combo社員ID_Change()

  Application.ScreenUpdating = False
  
  With Me.Combo社員ID
'    if .ListIndex < then Exit Sub
    If .ListIndex < 0 Then
      Exit Sub
    End If
    Combo社員ID.Value = .List(.ListIndex, 0)
    Text氏名.Value = .List(.ListIndex, 1)
    Text所属.Value = .List(.ListIndex, 2)
    '・
    '・
    '・
    Text標準報酬月額.Value = .List(.ListIndex, 22)
    Text市県民税.Value = .List(.ListIndex, 23)
  End With
  
'  Set r = Noting
  Set r = Nothing
  
  Application.ScreenUpdating = True
  
End Sub

【65522】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 9:14 -

引用なし
パスワード
   ▼八家九僧陀 さん:
お急ぎのようなのでとりあえず、現状報告

Comboboxの
BoundColumn= 2
ColumnCount = 2
RowSource = 適当に範囲を指定

Valueプロパティに普通の値(数値の1など)を代入するとエラーメッセージが再現できます。
このため、処理が止まるステップである、

TBL(Cnt) = vntData(1,Cnt) ←エラーメッセージのとき、ここが黄色に反転しています。

のTBL(Cnt) の中身がCombo社員IDであると考えられ、TBL(Cnt) にCombo社員IDをSetする処理と配列数の変更を行えば、とりあえず動作はすると考えられます。

【65523】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 9:38 -

引用なし
パスワード
   ▼八家九僧陀 さん:
調査結果です。
個人的には納得いかない仕様なので、可能なら他の方に追試をお願いしたいところですが。

BoundColumnに2を指定している場合、リストの2列目が値として使用されますが、この2列目のリストに存在しない値をValueプロパティに代入しようとすると問題のエラーメッセージが表示されます。
しかし、BoundColumnに1を指定した場合は、上記の問題は起こらず、コンボボックスに値が表示されます。
さらにValueプロパティではなく、TextColumnプロパティに代入すると、BoundColumnが2でもエラーは発生しませんが、コンボボックスに値が表示されません。

つまり、Combo社員ID.Valueに対し、リストの列2に存在しない値を代入しようとしてエラーが発生していると考えられます。
念のためですが、
TBL(Cnt) = vntData(1,Cnt)
という記述はプロパティの指定がないため、デフォルトプロパティが適用され、Valueプロパティがそれに該当するのでValueが用いられているはずです。

解決策としては、BoundColumnが1の状態で使用できるよう、元のリストの列位置変更するのが良いと思います。
なお、こちらの環境は2003です。

【65524】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 13:12 -

引用なし
パスワード
   ▼247b さん,Hirohumiさん、ありがとうございます。

TBL(Cnt).Value = vntData(1, Cnt) に修正しました。
ただTBL(Cnt)の次に「.」を入力したときに次候補がリストアップされますが、その中に「value」はなかったのですが(v候補はvisibleだけでしたが)、valueを加えました。

>BoundColumnに1を指定した場合は、上記の問題は起こらず、コンボボックスに値が表示されます。
>さらにValueプロパティではなく、TextColumnプロパティに代入すると、BoundColumnが2でもエラーは発生しませんが、コンボボックスに値が表示されません。
>
>つまり、Combo社員ID.Valueに対し、リストの列2に存在しない値を代入しようとしてエラーが発生していると考えられます。
>念のためですが、
>TBL(Cnt) = vntData(1,Cnt)
>という記述はプロパティの指定がないため、デフォルトプロパティが適用され、Valueプロパティがそれに該当するのでValueが用いられているはずです。
>
>解決策としては、BoundColumnが1の状態で使用できるよう、元のリストの列位置変更するのが良いと思います。
>なお、こちらの環境は2003です。

BoundColumnを「1」に修正したところ、User_Formが表示され、今までどおりのSheets("支給台帳")のデータが、spinボタンで前後させても表示されるようにはなりました。
早速Combo社員IDを選択すると、「社員ID」「氏名」の2列も表示されていました。
また、Combo社員ID中のリストを選択すると、ちゃんとTextboxに反映されました。
ただ、Combo社員ID中のリストの1行目、2行目を選択した場合に限り、「リストプロパティの値を取得できません。プロパティの配列のインデックスが不正です。」とのエラーメッセージが出て、デバッグで確認すると
  Text氏名.value = .List(.ListIndex, 1)の部分が黄色に反転しています。

次に、Spinボタンでデータを移動させると、当該行の社員ID,氏名が、Combo社員ID中のリストも黒く反転しているのですが、当該人Aの値がtextboxには反映されておらず、一旦、Combo社員ID中の別のID,氏名を選択してから、当該人Aを選択すると他のtextboxにも当該人Aの値が反映できました。(一旦別人を選択してから当該人を選択するというワンクッションを経なければ反映されない)
Spinボタンでデータを移動させずに(データを固定したままだと)、Combo社員IDを選択すると、次々とスムーズにいくのですが・・・・

しようとしていたのは、Spin移動したときも、Combo社員IDはChangeするので、そのChangeのたびに、当該人の値を代入できればと思っていたのですが、このCombo社員IDでのComboListからの取得方法自体が間違いで、例えば各TextBoxにVlookup関数なりで給与マスターから値を取得したほうが良かったのでしょうか?

【65525】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 14:41 -

引用なし
パスワード
   机上デバッグではそろそろ厳しい感じです。

Spin移動_changeプロシージャから処理開始した場合、「支給台帳」シートのデータが使用されていますが、Combo社員ID_Changeプロシージャから処理開始した場合、「仮マスター」シートのデータがCombo社員IDのリストとして使用されているので、「仮マスター」のデータが使用されます。
2つのシートに件数差等ないですか?

あと、おそらく現在の症状に関係ないと思いますが、
Spin移動.Minが0から開始なのに対し、「レコード数取得」プロシージャが「支給台帳」シートの件数−1を返し、「Userform_initialize」プロシージャで+1しているので、0からカウントすると1レコード余分になっていると思います。+1が不要かと。

>このCombo社員IDでのComboListからの取得方法自体が間違いで、例えば各TextBoxにVlookup関数なりで給与マスターから値を取得したほうが良かったのでしょうか?

配列変数を使用しても同じものは作れると思います。
また、
↓の処理を
Private sub Combo社員ID_Change()
Application.screenupdating = False
  With Me.Combo社員ID
  if .ListIndex < then Exit Sub
  Combo社員ID.value = .List(.ListIndex, 0)
  Text氏名.value = .List(.ListIndex, 1)
  Text所属.value = .List(.ListIndex, 2)
   ・
   ・
   ・
  Text標準報酬月額.value = .List(.ListIndex, 22)
  Text市県民税.value = .List(.ListIndex, 23)
End With

↓に置き換えたら、問題あるのでしょうか。
Private sub Combo社員ID_Change()
Application.screenupdating = False
データ表示 Me.Combo社員ID.ListIndex

【65528】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 15:47 -

引用なし
パスワード
   ▼247b さん:

本当にお世話になります。ありがとうございます。

>机上デバッグではそろそろ厳しい感じです。

「そろそろ厳しい感じです。」、なんだか不安になってきました。修復、改良は無理?って感じでしょうか?
>
>Spin移動_changeプロシージャから処理開始した場合、「支給台帳」シートのデータが使用されていますが、Combo社員ID_Changeプロシージャから処理開始した場合、「仮マスター」シートのデータがCombo社員IDのリストとして使用されているので、「仮マスター」のデータが使用されます。
>2つのシートに件数差等ないですか?

「支給台帳」は実際に当該月に給与を支給する者の人数です。
「仮マスター」は、現に社員登録している人数です。またデータ内容も時間外時間数や時間外手当額等の月々に変動するデータは登録されておらず、基本給、通勤費等、毎月毎月変動するようなデータではなく固定的、基本的なデータのみ登録しています。
具体的には、
「支給台帳」は、A列〜CR列、5月分は58行でした。
「仮マスター」は、A列〜W列で、66行です。

>
>あと、おそらく現在の症状に関係ないと思いますが、
>Spin移動.Minが0から開始なのに対し、「レコード数取得」プロシージャが「支給台帳」シートの件数−1を返し、「Userform_initialize」プロシージャで+1しているので、0からカウントすると1レコード余分になっていると思います。+1が不要かと。

具体的には、どの部分をどのように修正すればいいでしょう。

>配列変数を使用しても同じものは作れると思います。
>また、
>↓に置き換えたら、問題あるのでしょうか。
>Private sub Combo社員ID_Change()
>Application.screenupdating = False
>データ表示 Me.Combo社員ID.ListIndex

修正の仕方がわかりません。
何から何まで世話をおかけしますが、「With」以下はどうなるのでしょうか?

【65533】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 16:53 -

引用なし
パスワード
   >>Spin移動_changeプロシージャから処理開始した場合、「支給台帳」シートのデータが使用されていますが、Combo社員ID_Changeプロシージャから処理開始した場合、「仮マスター」シートのデータがCombo社員IDのリストとして使用されているので、「仮マスター」のデータが使用されます。
>>2つのシートに件数差等ないですか?
>
>「支給台帳」は実際に当該月に給与を支給する者の人数です。
>「仮マスター」は、現に社員登録している人数です。またデータ内容も時間外時間数や時間外手当額等の月々に変動するデータは登録されておらず、基本給、通勤費等、毎月毎月変動するようなデータではなく固定的、基本的なデータのみ登録しています。
>具体的には、
>「支給台帳」は、A列〜CR列、5月分は58行でした。
>「仮マスター」は、A列〜W列で、66行です。

仮マスターの情報が支給台帳の一部分であり、仮マスターに記載の有るデータは仮マスターから引いてきて、それ以外は支給台帳から引くか入力するということで理解しました。

>>あと、おそらく現在の症状に関係ないと思いますが、
>>Spin移動.Minが0から開始なのに対し、「レコード数取得」プロシージャが「支給台帳」シートの件数−1を返し、「Userform_initialize」プロシージャで+1しているので、0からカウントすると1レコード余分になっていると思います。+1が不要かと。
>
>具体的には、どの部分をどのように修正すればいいでしょう。
以下のプログラムに修正をいれていますので確認をお願いします。

机上デバッグが厳しいので、こちらで解釈した範囲でプログラムを作成してみました。
かえって混乱するようでしたら、使用は避けてください。
修正、追加箇所に247bとコメントを入れてあります。
修正していないプロシージャは削除してあります。
クラスモジュールは新規に追加してから以下に記述のプログラムをコピペしてください。
なお、クラスの名前は「clsFinder」にしてあります。

'Option Explicit

Dim TBL(1 To 90) As Control
Dim データ範囲 As Range
Dim r As Range '←今回の追加
Dim DataFinder As clsFinder '247b add

Private Sub Userform_initialize()

'///////// ココから新規追加(質問箱から盗用)
Set r = Worksheets("仮マスター").Range("A1").CurrentRegion
Set r = Intersect(r, r.Offset(1))
Set DataFinder = New clsFinder '247b add

'With Combo社員ID 247b del
'  .RowSource = r.Address(external:=True)
'  .ColumnHeads = True
'  .TextColumn = 1
'  .BoundColumn = 2
'  .ColumnCount = 2
'  .ColumnWidths = "40:60"
'End With
'////// ココまで
Set DataFinder.ターゲット範囲 = r '247b add
DataFinder.社員ID列 = 1 '247b add


'Spin移動.Max = レコード数取得 + 1
Spin移動.Max = レコード数取得 '247b rep

Set TBL(1) = text支給年月日
Set TBL(2) = text種別
Set TBL(3) = Combo社員ID '←このIDにより以下の約20個のtextboxに値を取得
Set TBL(4) = Text氏名
'〜
Set TBL(96) = text差引支給額 'Combo社員ID以外は全てtextBoxです

Set データ範囲 = Worksheets("支給台帳").Range("A1").CurrentRegion

If データ範囲.Rows.Count = 1 Then
Else
データ表示 2
End If
End Sub

Public Function レコード数取得() As Integer
レコード数取得 = Worksheets("支給台帳").Range("A1").CurrentRegion.Rows.Count - 1
End Function

Public Sub データ表示(行数 As Integer)
  Dim Cnt As Integer, vntData As Variant
  vntData = Worksheets("支給台帳").Range("A1").CurrentRegion.Rows(行数).Value
  
  For Cnt = 1 To 96 Step 1
    TBL(Cnt) = vntData(1, Cnt) '←エラーメッセージのとき、ここが黄色に反転
  Next
  
  Textレコード.Value = Spin移動.Value - 1 & "/" & レコード数取得
End Sub

Private Sub Spin移動_change()
If データ範囲.Rows.Count <> 1 Then
データ表示 (Spin移動.Value)
End If
End Sub


'////////////////////////// ココから新規追加(質問箱から盗用)
Private Sub Combo社員ID_Change()
  Application.ScreenUpdating = False
  With Combo社員ID
    If .ListIndex < 1 Then Exit Sub
'    Combo社員ID.Value = .List(.ListIndex, 0) 247b del
'    Text氏名.Value = .List(.ListIndex, 1)
'    Text所属.Value = .List(.ListIndex, 2)
'    '〜
'    Text標準報酬月額.Value = .List(.ListIndex, 22)
'    Text市県民税.Value = .List(.ListIndex, 23)
    If DataFinder.Find社員(Combo社員ID.List(Combo社員ID.ListIndex, 0)) Then '247bAdd
      Combo社員ID.Value = DataFinder.GetValue(1)
      Text氏名.Value = DataFinder.GetValue(2)
      Text所属.Value = DataFinder.GetValue(3)
      '〜
      Text標準報酬月額.Value = DataFinder.GetValue(22)
      Text市県民税.Value = DataFinder.GetValue(23)
    End If
  End With
  Set r = Noting
  Application.ScreenUpdating = True
End Sub


Option Explicit

'これはクラスモジュールです。
'クラスモジュールを新規作成し、プログラムを貼り付けてください。
'プロパティウィンドウの(オブジェクト名)を「clsFinder」に変更してください。


Private Rng As Range
Private colnum As Long
Private TargetRow As Range

Public Property Set ターゲット範囲(vObject As Range)
  Set Rng = vObject
End Property

Public Property Let 社員ID列(vdata As Long)
  colnum = vdata
End Property

Public Function Find社員(ID As Variant) As Boolean
  Dim rg As Range
  Set rg = Rng.Columns(colnum).Find(ID, LookIn:=xlValues, LookAt:=xlWhole)
  If Not rg Is Nothing Then
    Set TargetRow = rg.EntireRow
    Find社員 = True
  Else
    Set TargetRow = Nothing
    Find社員 = False
  End If
End Function

Public Function GetValue(Col As Long) As Variant
  If Not TargetRow Is Nothing Then
    GetValue = TargetRow.Cells(1, Col).Value
  End If
End Function

【65535】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 19:08 -

引用なし
パスワード
   ▼247b さん:
ご親切に新たなコードまでご教示いただき本当にありがとうございます。

まず、
>'Spin移動.Max = レコード数取得 + 1

>Spin移動.Max = レコード数取得
に修正したところ、支給台帳の最終行のデータが反映されません。
TextレコードでSPIN移動の現在行を表示しているのですが、56/57までで57/57の表示がされません。(最終行は57行)

またご教示いただいたコードを修正、追記しました。

また新規の
>'これはクラスモジュールです。
>'クラスモジュールを新規作成し、プログラムを貼り付けてください。
>'プロパティウィンドウの(オブジェクト名)を「clsFinder」に変更してください。
のご指示どおり、クラスモジュール作成もしましたが、

実行すると、まず何らのエラーメッセージもされず、通常にUSER_FORMも表示されますが、Combo社員ID欄は空欄で、リストが表示されていません。
後、次の修正部分で、「If .ListIndex < 1 Then Exit Sub」は、そのまま残せばいいんですね?
>  With Combo社員ID
>    If .ListIndex < 1 Then Exit Sub
>'    Combo社員ID.Value = .List(.ListIndex, 0) 247b del
>'    Text氏名.Value = .List(.ListIndex, 1)
>'    Text所属.Value = .List(.ListIndex, 2)> 

引き続きお助けください!!!!!

【65536】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 20:50 -

引用なし
パスワード
   ▼八家九僧陀 さん:
>▼247b さん:
>ご親切に新たなコードまでご教示いただき本当にありがとうございます。
>
>まず、
>>'Spin移動.Max = レコード数取得 + 1
>を
>>Spin移動.Max = レコード数取得
>に修正したところ、支給台帳の最終行のデータが反映されません。
>TextレコードでSPIN移動の現在行を表示しているのですが、56/57までで57/57の表示がされません。(最終行は57行)

だとしたら、こちらの想定が間違っているのでしょう。元に戻してください。余計なことを言ってしましました。すみません

>またご教示いただいたコードを修正、追記しました。
>
>また新規の
>>'これはクラスモジュールです。
>>'クラスモジュールを新規作成し、プログラムを貼り付けてください。
>>'プロパティウィンドウの(オブジェクト名)を「clsFinder」に変更してください。
>のご指示どおり、クラスモジュール作成もしましたが、
>
>実行すると、まず何らのエラーメッセージもされず、通常にUSER_FORMも表示されますが、Combo社員ID欄は空欄で、リストが表示されていません。

リストが表示されていない、とは、リストの中身が無くなっているということですよね?
それは
'With Combo社員ID 247b del
'  .RowSource = r.Address(external:=True)
'  .ColumnHeads = True
'  .TextColumn = 1
'  .BoundColumn = 2
'  .ColumnCount = 2
'  .ColumnWidths = "40:60"
'End With
をコメントにしたからだと思います。
いったん、上記部分のコメントを外してみてもらえますか。
こちらから追加した部分はそのまま残してください。


>後、次の修正部分で、「If .ListIndex < 1 Then Exit Sub」は、そのまま残せばいいんですね?
>>  With Combo社員ID
>>    If .ListIndex < 1 Then Exit Sub
>>'    Combo社員ID.Value = .List(.ListIndex, 0) 247b del
>>'    Text氏名.Value = .List(.ListIndex, 1)
>>'    Text所属.Value = .List(.ListIndex, 2)> 
>
>引き続きお助けください!!!!!

If .ListIndex < 1 Then Exit Sub
のステップについては、一番最初の投稿では
If .ListIndex < Then Exit Sub
となっていたので、おそらくこうだろうという修正を加えた部分です。
想像の範囲を超えませんが、If .ListIndex < 0 Then Exit Sub
にすべきであると思います。

    If DataFinder.Find社員(Combo社員ID.List(Combo社員ID.ListIndex, 0)) Then '247bAdd
      Combo社員ID.Value = DataFinder.GetValue(1)
      Text氏名.Value = DataFinder.GetValue(2)
      Text所属.Value = DataFinder.GetValue(3)
      '〜
      Text標準報酬月額.Value = DataFinder.GetValue(22)
      Text市県民税.Value = DataFinder.GetValue(23)
    End If
のIF文の下の処理が実行されるか確認できますか?
IF文のステップにブレークポイントを置くと処理がそこで止まります。
ブレークポイントが解らない場合はレスしてください。

【65537】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 22:06 -

引用なし
パスワード
   ▼247b さん:
ほんとに世話のかける奴ですみません。

'Spin移動.Max = レコード数取得 + 1 に戻し、元に戻りました。
>
>
>'With Combo社員ID 247b del
>'  .RowSource = r.Address(external:=True)
>'  .ColumnHeads = True
>'  .TextColumn = 1
>'  .BoundColumn = 2
>'  .ColumnCount = 2
>'  .ColumnWidths = "40:60"
>'End With

いったん、上記部分のコメントを外しました。
Combo社員IDに、リストが復帰しました。
各TextBoxにも値が反映されています。

ただ、何故か、リストの1行目、2行目はクリックしても何も反応がありません。(反映されるべきTextBoxに値がされず、リストの3行目以降の人を選択すると反映されます。)
また、やはりSPIN移動をさせたタイミングでは各TextはChangeせず、Combo社員IDで、一旦前後の人を仮選択してから当該人をクリックしないと当該人の値が反映されません。

例:SPIN移動で 7/57番目の社員IDが12345の人をUserFormに表示しているとします。
Combo社員IDのリストも「12345 鳩山由起夫」が黒く反転しています。
それをクリックしても、他のTextには反応無く、一旦Combo社員IDのリストの次の「12346 小沢一郎」をクリックします。(このとき、他のTextには12346小沢一郎の値がちゃんと反映されます。)次にもう一度「12345 鳩山由起夫」をクリックすると他のTextには12345 鳩山由起夫の値がちゃんと反映されるという具合です。
うっかりすると、7/57番目は12345のデータであるのに、12346を一旦表示させたものを、ここでうっかり更新ボタンをクリックしてしまうと7/57番目が12346に変更されてしまい、12345が消失してしまう、また12346が重複して存在してしまうことになるので、SPIN移動でChangeした段階でリストから値を取得したいのですが????

何とかいい方法はないでしょうか???

【65538】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 22:39 -

引用なし
パスワード
   >例:SPIN移動で 7/57番目の社員IDが12345の人をUserFormに表示しているとします。
>Combo社員IDのリストも「12345 鳩山由起夫」が黒く反転しています。
>ただ、何故か、リストの1行目、2行目はクリックしても何も反応がありません。(反映されるべきTextBoxに値がされず、リストの3行目以降の人を選択すると反映されます。)
>また、やはりSPIN移動をさせたタイミングでは各TextはChangeせず、Combo社員IDで、一旦前後の人を仮選択してから当該人をクリックしないと当該人の値が反映されません。

1行目、2行目のみ動作しないというのは、どこかにListIndexが0又は1の時に処理しない(またはListIndexが1より大きい場合に処理する)という条件文があるからだと思うのですが、こちらでは特定できてません。

>それをクリックしても、他のTextには反応無く、一旦Combo社員IDのリストの次の「12346 小沢一郎」をクリックします。(このとき、他のTextには12346小沢一郎の値がちゃんと反映されます。)次にもう一度「12345 鳩山由起夫」をクリックすると他のTextには12345 鳩山由起夫の値がちゃんと反映されるという具合です。
>うっかりすると、7/57番目は12345のデータであるのに、12346を一旦表示させたものを、ここでうっかり更新ボタンをクリックしてしまうと7/57番目が12346に変更されてしまい、12345が消失してしまう、また12346が重複して存在してしまうことになるので、SPIN移動でChangeした段階でリストから値を取得したいのですが????

SPINで鳩山由起夫を表示させた後、Comboboxで鳩山由起夫を選択しても反応がないという意味でしょうか。そうだとすると、Changeイベントとしては仕様通りの動きだと思います。
Spin移動_changeプロシージャを以下のように追記してみてください。

Private Sub Spin移動_change()
  if データ範囲.Rows.Count<> 1 then
    データ表示(Spin移動.Value)
    Combo社員ID_Change '247b
  End if
End sub

【65539】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/2(水) 22:45 -

引用なし
パスワード
   試しに、以下のステップをコメントにしてみてください。

Private sub Combo社員ID_Change()
Application.screenupdating = False
  With Me.Combo社員ID
  if .ListIndex < then Exit Sub ←ここをコメントにする。

【65540】Re:User_formの修復について(至急!!!...
質問  八家九僧陀  - 10/6/2(水) 23:42 -

引用なし
パスワード
   ▼247b さん:
ありがとうございます。

>Spin移動_changeプロシージャを以下のように追記したところ、見事に連動して各Text値もChangeしました。
ただ相変わらずリスト1行目、2行目は反応せず、3行目からはChangeします。

大事なことだったのかも知れませんが、リスト一行目は支給台帳の一行目に存在し、リスト2行目の人は、今月の支給台帳にはありません。
ただ、直接Combo社員IDで選択しても、相変わらず反応(値が不変)しません。

>
>Private Sub Spin移動_change()
>  if データ範囲.Rows.Count<> 1 then
>    データ表示(Spin移動.Value)
>    Combo社員ID_Change '247b
>  End if
>End sub


>試しに、以下のステップをコメントにしてみてください。
>
>Private sub Combo社員ID_Change()
>Application.screenupdating = False
>  With Me.Combo社員ID

>  if .ListIndex < then Exit Sub ←ここをコメントにする。
「'」でコメントにして実行すると「リストプロパティの値を取得できません。プロパティの配列のインデックスが不正です。」とエラー表示され、UESERFORMも表示されませんでした。

【65541】Re:User_formの修復について(至急!!!...
発言  247b  - 10/6/3(木) 0:19 -

引用なし
パスワード
   ▼八家九僧陀 さん:
>▼247b さん:
>ありがとうございます。
>
>>Spin移動_changeプロシージャを以下のように追記したところ、見事に連動して各Text値もChangeしました。
>ただ相変わらずリスト1行目、2行目は反応せず、3行目からはChangeします。
>
>大事なことだったのかも知れませんが、リスト一行目は支給台帳の一行目に存在し、リスト2行目の人は、今月の支給台帳にはありません。

Userform_initializeプロシージャで、ColumnHeadsをTrueにしているので、1行目の人がヘッダー扱いになって選択不可になってたりしませんか? ヘルプによると、1行目をヘッダーに使うとあったように記憶しています。
2行目の人は、支給台帳に存在していないことが原因の可能性が高いように思います。

Private sub Userform_initialize()

'///////// ココから新規追加(質問箱から盗用)
Set r = worksheets("仮マスター").Range("A1").CurrentRegion
Set r = intersect(r,r.Offset(1))

With Me.Combo社員ID
  .rowsource = r.address(external:=True)
  .ColumnHeads = True  ←試すとしたら、ここをコメントにしてみることが考えられます。

>ただ、直接Combo社員IDで選択しても、相変わらず反応(値が不変)しません。
試しに以下のように修正してみてください。動かない場合は元に戻してください。

Private Sub Spin移動_change

Private Sub Spin移動_Click


>>
>>Private Sub Spin移動_change()
>>  if データ範囲.Rows.Count<> 1 then
>>    データ表示(Spin移動.Value)
>>    Combo社員ID_Change '247b
>>  End if
>>End sub
>
>
>>試しに、以下のステップをコメントにしてみてください。
>>
>>Private sub Combo社員ID_Change()
>>Application.screenupdating = False
>>  With Me.Combo社員ID
>
>>  if .ListIndex < then Exit Sub ←ここをコメントにする。
>「'」でコメントにして実行すると「リストプロパティの値を取得できません。プロパティの配列のインデックスが不正です。」とエラー表示され、UESERFORMも表示されませんでした。

このメッセージが出る原因については探るのに少し時間がかかりそうな気がします。とりあえず、元に戻しておくので良いのではないでしょうか。

とりあえず、おやすみなさい。

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