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

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

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

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

Q&A

解決済

2回答

1735閲覧

空白のセルを上書きして数値を書き込むやり方 VBA

milk1218

総合スコア20

VBA

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

0グッド

0クリップ

投稿2021/09/28 03:18

前回も質問させていただいた出退勤システムです。
前回までは出勤時刻も退勤時刻も一度に入力していたので、上から順に入っていったのですが
今回出勤時間を入力したら閉じて、退勤時に退勤時間と休憩時間・・・とタイミングをバラバラにしても
上から詰めて登録するようにしたいのですが、入力タイミングを分けると画像のようになってしまいます。

イメージ説明
イメージ説明

流れとしては、ユーザーフォームで年月日をプルダウンで選択し、出勤時刻をテキストボックスで
入力して登録して、一旦ユーザーフォームを閉じた後にもう一回開いて
今度は休憩時間と退勤時間を入れたのですが
改行されてしまい、ズレてしまいます・・・。

※以下は時刻を登録するユーザーフォームの画像です。
イメージ説明

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

該当のソースコード

Private Sub cb_touroku_Click() '登録 Dim tgtRow As Long tgtRow = Cells(32, 1).End(xlUp).Row tgtRow = tgtRow + 1 For i = 2 To 32 For Each SH In ActiveWorkbook.Worksheets With ActiveSheet .Cells(tgtRow, 1).Value = Me.cb1.Value .Cells(tgtRow, 2).Value = Me.cb2.Value .Cells(tgtRow, 3).Value = Me.cb3.Value .Cells(tgtRow, 4).Value = Me.TextBox1.Value       '出勤時刻  時 .Cells(tgtRow, 5).Value = Me.TextBox2.Value       '出勤時刻  分 .Cells(tgtRow, 6).Value = Me.TextBox3.Value        '退勤時刻 時 .Cells(tgtRow, 7).Value = Me.TextBox4.Value       '退勤時刻  分 .Cells(tgtRow, 8).Value = Me.TextBox5.Value       '休憩時刻  時 .Cells(tgtRow, 9).Value = Me.TextBox6.Value      '休憩時刻  分 .Cells(tgtRow, 10).Value = Me.TextBox7.Value     '休憩時刻  時 .Cells(tgtRow, 11).Value = Me.TextBox8.Value      '休憩時刻 分 End With Next Next i MsgBox "登録しました" End Sub Private Sub UserForm_Initialize() With cb1                '年プルダウン .AddItem "2021" End With With cb2                '月プルダウン .AddItem "1" .AddItem "2" .AddItem "3" .AddItem "4" .AddItem "5" .AddItem "6" .AddItem "7" .AddItem "8" .AddItem "9" .AddItem "10" .AddItem "11" .AddItem "12" End With With cb3                     '日付プルダウン .AddItem "1" .AddItem "2" .AddItem "3" .AddItem "4" .AddItem "5" .AddItem "6" .AddItem "7" .AddItem "8" .AddItem "9" .AddItem "10" .AddItem "11" .AddItem "12" .AddItem "13" .AddItem "14" .AddItem "15" .AddItem "16" .AddItem "17" .AddItem "18" .AddItem "19" .AddItem "20" .AddItem "21" .AddItem "22" .AddItem "23" .AddItem "24" .AddItem "25" .AddItem "26" .AddItem "27" .AddItem "28" .AddItem "29" .AddItem "30" .AddItem "31" End With End Sub

試したこと

他の質問者様でチラホラ「空白のセルを消して上に詰める」質問があったので参考したのですが
上手くいきませんでした・・・。

Dim MyRng As Range
Set MyRng = Range(F:K) '退勤時間から休憩時間の範囲
MyRng.SpecialCells(xlCellTypeBlanks).Delete shift:=xlShiftUp '範囲に含まれる空白セルを削除

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

回答ではないですが、ちょっと気になったので。

あきらかに無駄なコードがあります。
どこかのサンプルコードを参考にするのはいいのですが、コードの意味を理解して使いましょう。

vba

1For i = 2 To 32 2 3For Each SH In ActiveWorkbook.Worksheets 4 With ActiveSheet 5 .Cells(tgtRow, 1).Value = Me.cb1.Value 6 .Cells(tgtRow, 2).Value = Me.cb2.Value 7 .Cells(tgtRow, 3).Value = Me.cb3.Value 8 .Cells(tgtRow, 4).Value = Me.TextBox1.Value       '出勤時刻  時 9 .Cells(tgtRow, 5).Value = Me.TextBox2.Value       '出勤時刻  分 10 .Cells(tgtRow, 6).Value = Me.TextBox3.Value        '退勤時刻 時 11 .Cells(tgtRow, 7).Value = Me.TextBox4.Value       '退勤時刻  分 12 .Cells(tgtRow, 8).Value = Me.TextBox5.Value       '休憩時刻  時 13 .Cells(tgtRow, 9).Value = Me.TextBox6.Value      '休憩時刻  分 14 .Cells(tgtRow, 10).Value = Me.TextBox7.Value     '休憩時刻  時 15 .Cells(tgtRow, 11).Value = Me.TextBox8.Value      '休憩時刻 分 16 End With 17 18Next 19Next i

上記のコードでFor ... Next文が2つあります。
For i = 2 To 32 は i を2から32まで一つずつ変化させて繰り返し実行するという意味です。
For Each SH In ActiveWorkbook.Worksheetsはブックのすべてのシートに対して処理をする場合に使用します。
ところが、このループ内で i は使っていないし、対象シートは ActiveSheet だけです。
ループでの繰り返しは無駄に同じところの上書きしているだけになります。

ですので、この2つの For ... Next文は不要です。

さらに、余計なお節介をすれば、
年月日を3セルに、時刻を2セルに分けて入力していますが、
今後、このデータを利用して集計などを行うと思いますが、
そのとき、面倒なことになります。

下記のように年月日、時刻、ぞれぞれ1セルに代入するようにした方がいいでしょう。

vba

1 With ActiveSheet 2 .Cells(tgtRow, 1).Value = DateSerial(Me.cb1.Value, Me.cb2.Value, Me.cb3.Value) 3 .Cells(tgtRow, 2).Value = TimeSerial(Me.TextBox1.Value, Me.TextBox2.Value, 0)'出勤時刻 4 .Cells(tgtRow, 3).Value = TimeSerial(Me.TextBox3.Value, Me.TextBox4.Value, 0)'退勤時刻 5 .Cells(tgtRow, 4).Value = TimeSerial(Me.TextBox5.Value, Me.TextBox6.Value, 0)'休憩開始時刻 6 .Cells(tgtRow, 5).Value = TimeSerial(Me.TextBox7.Value, Me.TextBox8.Value, 0)'休憩終了時刻 7 End With

そうすれば下記のように簡単な式で勤務時間を計算できますし、見やすいと思います。

イメージ説明

投稿2021/09/28 04:27

編集2021/09/28 05:25
hatena19

総合スコア33808

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

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

milk1218

2021/09/28 05:39

とてもご丁寧にご説明・ご指摘いただきありがとうございます・・・! Next文が2つについて解説ありがとうございます・・・!全く気づきませんでした・・・・。 入力時刻も理想としては添付していただいた画像のように仕上げたかったので助かりました・・・!
guest

0

入力行は、以下で求めていますよね。

tgtRow = Cells(32, 1).End(xlUp).Row tgtRow = tgtRow + 1

これを退勤時には、「tgtRow = tgtRow + 1」しないようにすればよいのでは?
ただ、「退勤」時には、「出勤時間」は入力しないでしょうから、そうすると、空白で上書きしてしまうことになりますね。
「出勤」と「退勤」でボタンを分けるなどして、入力項目も分けたほうが良いと思います。

投稿2021/09/28 03:44

hex309

総合スコア761

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

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

milk1218

2021/09/28 04:13

tgtRow = tgtRow + 1をしないで「出勤」「退勤」でボタンを分けたら並んでくれました・・!! やはり処理を分けるのが無難みたいですね・・・。 ありがとうございます!!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問