質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

983閲覧

複数のシートとテキストボックスがある場合の保存と出力

milk1218

総合スコア20

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2021/10/16 12:40

前提・実現したいこと

テキストボックスに転記、セルからテキストボックスへ値を出力が上手くいきません。
前回の質問でご回答頂いたコードを参考に進めていますが
現状、ユーザーフォームを開いても各テキストボックスに値は表示されず、テキストボックスから
セルへの暗記も424エラーが出てしまい上手くいかない状態です。

そもそもシートが複数あるので、どのシートのセルなのか判断できていないのか
(月選択の際に該当シートがSelectされるようにはしていますが、保存出力のところで反映されていないのか)
テキストボックスで入力する際に「10:00」と手入力するけど、format関数が必要なのか・・・。
構造体で「date」を使っていて、テキストボックスでは文字列(string)だからなのか・・。
ご教授頂けると幸いです・・・(今回構造体の使用が必須となっています)

上記のように様々な要素が思い当たるのですが、例としてよくある
Sub macro1()
Call func1
End Sub

Function func1() As String
MsgBox "Hello VBA!"
End Function

みたいに最初から入れるものが分かっているわけではない、尚且つ今回みたいに日にち指定の
テキストボックスが複数あるパターンの書き方がいまいち理解出来ていないためこのタイプのエラーでずっと躓いています・・。

イメージ説明

発生している問題・エラーメッセージ

monthly(i).starttime = Cells(i + 2, 3)の部分で「424: オブジェクトが必要です」のエラー 恐らくこの下もそうなります・・。ここで出るということは出力の Me.Controls("txtStarttime" & i).Value = monthly(i).starttime の部分も可能性はあると思っています。

該当のソースコード

Type attendance                    '標準モジュール starttime As Date '始業時刻 endtime As Date '終業時刻 breakstart As Date '休憩時間のはじめ breakend As Date '休憩時間のおわり worktime As Single '実働時間 note As String '備考 End Type '以下はユーザーフォーム Private Sub cmbMonth_Change()      '月選択プルダウン ※選んだ月のシートがセレクト状態になる SetWeekLabel On Error Resume Next Worksheets(cmbMonth.Text).Select Dim i As Integer For i = 1 To 12 cmbMonth.AddItem i Next End Sub Private monthly() As attendance 'オブジェクトの定義 Public Sub AttendanceSave() '勤怠保存 ReDim monthly(1 To 31) Dim i As Long For i = 1 To 31 monthly(i).starttime = Cells(i + 2, 3) monthly(i).endtime = Cells(i + 2, 4) monthly(i).breakstart = Cells(i + 2, 5) monthly(i).breakend = Cells(i + 2, 6) monthly(i).worktime = Cells(i + 2, 7) monthly(i).note = Cells(i + 2, 8) Next i End Sub Public Sub SetAttendance() '勤怠出力 Dim i As Long Sheets(cmbMonth.Value).Activate For i = LBound(monthly) To UBound(monthly) Me.Controls("txtStarttime" & i).Value = monthly(i).starttime Me.Controls("txtEndtime" & i).Value = monthly(i).endtime Me.Controls("txtBreakstart" & i).Value = monthly(i).breakstart Me.Controls("txtBreakend" & i).Value = monthly(i).breakend Me.Controls("txtWorktime" & i).Value = monthly(i).worktime Me.Controls("txtNote" & i).Value = monthly(i).note Next i End Sub Private Sub CommandButton1_Click()      '更新ボタン(テキストボックスからセルへの登録処理) Call AttendanceSave Call SetAttendance End Sub

試したこと

試しに本来の構造ではないのですが(テキストボックスが31日分あるので)
テキストボックスを6個にして、txtStarttime1などの1のものだけ使用して
やったら424のエラーは出ませんでした(それでも本来やりたいことのセルへの暗記は出来ませんでしたが・・・)

補足情報(FW/ツールのバージョンなど)

・シート上での時刻系のセルの書式設定は「日付」
・実働時間は手入力ではなく、始業時刻と終業時刻から休憩時間を引いた時間で
出力されるようしたいのですが、現状はそちらはまだまだ未着手なのでそのままです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

イベントの使い方が理解できていないですね。

現状、ユーザーフォームを開いても各テキストボックスに値は表示されず、

フォームを開いたときに何かしたいときは、フォームのInitializeイベントに記述します。UserForm_Initialize()

Initializeイベントでするべき処理としては、
年コンボボックスのリストと初期値の設定
月コンボボックスのリストと初期値の設定
各テキストボックスへシートのデータの転記
となります。

月を選択したときの処理は、コンボボックスのChangeイベントになります。
cmbMonth_Change()
ここで、選択した月のシートからテキストボックスへの転記をします。

モジュール内で共通で使う変数は、モジュールの先頭で宣言します。
monthly() As attendance

ユーザーフォームモジュール

vba

1Option Explicit 2 3Private monthly() As attendance '構造体の配列を宣言 4 5Private Sub UserForm_Initialize() 6 Dim i As Integer 7 8 '年をどのように管理するか不明なので、 9 'とりあえず当年、来年の西暦をリストに設定 10 For i = 0 To 1 11 cmbYear.AddItem Year(Date) + i 12 Next 13 cmbYear.Value = Year(Date) 'とりあえず当年を初期値に 14 15 16 For i = 1 To 12 'シートは1から12まである前提 17 cmbMonth.AddItem i 18 Next 19 cmbMonth.Value = Month(Date) 'とりあえず当月を初期値に 20 '初期値を設定することで cmbMonth_Change が呼び出される 21End Sub 22 23Private Sub cmbMonth_Change() '月選択プルダウン 24 Debug.Print cmbMonth.Value 25 Worksheets(cmbMonth.Value).Select '先に月シートを選択してから 26 '曜日設定やテキストへの転記をする 27 28 SetWeekLabel '曜日設定 29 Call AttendanceSave '選択したシートデータを構造体配列へ 30 Call SetAttendance '構造体配列からテキストへ 31End Sub 32 33'以下略

補足

以前の質問のコメントでも確認したのですが(その時はまだ考えていないとのことでしたが)、
年の管理をどうするのかそろそろ決めたほうがいいと思います。

現状のシート名を1~12にしていると設計だと年ごとにブックを分ける必要がでてきます。
これだと、ユーザーフォームは年のブックとは別のブックに置いて、
そこから年コンボボックスの選択で、年ブックをアクティブにする(開いてなければ開く)というような処理が必要になります。

あるいは、シート名を 2021/10 というようにするという方法も考えられます。
そうすれば、ブックは一つですみます。

あと、勤怠管理する社員が一人ということではないと思いますので、社員をどう管理するかも、考える必要があります。

これも、社員毎にブックをわけるのか、一括で管理するのか。

社員数が多いとデータベース的な考え方で管理する必要も出てくるように思いますが、
そうなると、今のスキルレベルではかなりハードルは高そうですね。

投稿2021/10/16 14:48

編集2021/10/16 15:24
hatena19

総合スコア33790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

milk1218

2021/10/17 07:30

ありがとうございます・・・!コンパイルエラーが出なくなりました。イベントの使い分けもご説明いただきありがとうございます!! 現状ですとシート名を2021/10するのが一番近道ではあるので、そうしたいとは思っています・・。 実を言うと、仰る通りこの後保存出力処理が完成したらデータベースで管理する方向に持っていかなくてはいけないので、正直かなり厳しいとは思っています・・。 そして追記ですみません・・!エラーコードは出なくなったのですが、デフォルトで「0:00:00」が始業~休憩時間の部分に、「0」が実働と備考に出ていて保存出力自体はまだ出来ていないのですが、これはセル上の書式設定の問題でしょうか・・。時刻からユーザー定義や文字列にしたのですが変化は無くて・・。それともFORMAT関数が必要なのでしょうか・・?
guest

0

VBA

1 2'以下はユーザーフォーム 3Option Explicit 4 5Private monthly() As attendance 'オブジェクトの定義 6 7Private Sub cmbMonth_Change()   8'(以下略) 9 10

投稿2021/10/16 12:59

jinoji

総合スコア4585

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

milk1218

2021/10/16 13:35

ありがとうございます・・・! コピペでオブジェクト定義の下に移動させたのですが、同じエラーが出てきてしまいました・・。
jinoji

2021/10/16 13:40

エラーになったときのmonthlyの型はどうなってますか?
milk1218

2021/10/17 07:30

すみません・・!コンパイルエラーはおかげさまで解決致しました・・! ありがとうございました・・・!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問