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

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

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

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

Q&A

解決済

2回答

1326閲覧

登録内容の確認、上書き

care_raisu

総合スコア7

VBA

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

0グッド

0クリップ

投稿2020/03/27 05:12

編集2020/03/27 05:19

前提・実現したいこと

何度も申し訳ございません。

調べてもわからないのでヒント等教えていただければ幸いです。

ユーザーフォームに登録いうボタンがあるのですが、
そのボタンを押した際、E列を検索し同じ日にちと社員番号があれば
上書きするかの確認と、上書きしてもOKな場合、内容の上書き

登録済のものがなければ新規で登録したいと思っています。

新規の登録の方はうまくいくのですが検索上書きがうまくできません、、

説明がへたくそなためわかりづらく大変申し訳ないのですが解決策等ございましたら
教えていただきたいです。よろしくお願いいたします。

||C|D|E|F|G|H|
|:--|:--:|--:|
|1|予定日|社員番号|=C&E|行先1|行先2|戻時間|
|2|3/10|1234|439001234|新規|登録|しました|
|3|3/11|1234|439011234|新規|登録|しました|
|4|3/12|1234|439021234|新規|登録|しました|
|5|3/13|1234|439031234|新規|登録|しました|

(E列には=C1&E1を相対コピーするコードを書いて入れています)

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

For

1If Tgtnm = Date1 + i & 1234 Then 2Tgtnm.Select 3msg = MsgBox("登録済ですが上書きしますか?", Buttons:=vbYesNo) 4If msg = vbYes Then 5ActiveCell.Offset(0, 1) = "上書き" 6ActiveCell.Offset(0, 2) = "され" 7ActiveCell.Offset(0, 3) = "ました" 8Else 9MsgBox "入力を終了します" 10End If

上記コードを上書き、検索に使えるだろうと思いコードを書いていったですが
上書きどころか新規での登録もできなくなってしまいました。

間違っているところはここだと思っていますが他にも修正すべき点、解決策や改善策等あれば教えていただきたいです<(_ _)>

該当のソースコード

VBA

1Sub btm登録() 2 Dim Date1 As Date 3 Dim Date2 As Date 4 Dim i, j, lastRow 5 Dim ws As Worksheet 6 Dim Tgtnm As Variant 7 Dim msg As VbMsgBoxResult 8 9 10 Set ws = Worksheets("予定表") 'シートセット 11 12 Date1 = txt予定日.value '例)3/10 13 Date2 = txt帰社日.Value '例)3/13 14 15 lastRow = ws.Cells(Rows.Count, 3).End(xlUp).Row '一番下の行の取 16 ws.Activate 'シートの選択 17 18 For i = 0 To DateDiff("d", Date1, Date2) 19 For Each Tgtnm In Range("E:E") 20 If Tgtnm = Date1 + i & 1234 Then 21 Tgtnm.Select 22 msg = MsgBox("登録済ですが上書きしますか?", Buttons:=vbYesNo) 23 If msg = vbYes Then 24 ActiveCell.Offset(0, 1) = "上書き" 25 ActiveCell.Offset(0, 2) = "され" 26 ActiveCell.Offset(0, 3) = "ました" 27 Else 28 MsgBox "入力を終了します" 29 End If 30 Else 31 Cells(i + lastRow + 1, 3) = DateAdd("d", i, Date1) 32 Cells(i + lastRow + 1, 4) = txt社員番号'例)1234 33 Cells(i + lastRow + 1, 5).FormulaR1C1 = Cells(i + lastRow, 5).FormulaR1C1 34 Cells(i + lastRow + 1, 6) = "新規" 35 Cells(i + lastRow + 1, 7) = "登録" 36 Cells(i + lastRow + 1, 8) = "しました" 37 End If 38 Next 39 Next 40End Sub 41``` 42 43### 補足情報(FW/ツールのバージョンなど) 44エクセル2016

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

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

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

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

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

sinzou

2020/03/27 08:34 編集

案の一つとして、セル値サーチしているときは、上書きするかの判断を行い 上書きなければ新規登録する。 フラグ変数を用意し0値とする 該当セル見つかれば(上書)フラグを1にする 新規登録はFor Each の外でフラグが0であれば行う。
guest

回答2

0

ExcelVBA

1Private Sub CommandButton1_Click() 2 Dim rngList As Range 3 Dim rngKey As Range 4 Dim strBegin As String 5 Dim strEnd As String 6 Dim ixTop As Long 7 Dim ixBottom As Long 8 9 Set rngList = Worksheets("Sheet1").Range("C1").CurrentRegion 10 Set rngKey = rngList.Columns("E").Cells 11 strBegin = CLng(CDate(Me.TextBox2.Text)) & Me.TextBox1.Text 12 strEnd = CLng(CDate(Me.TextBox3.Text)) & Me.TextBox1.Text 13 14 '検索 15 On Error Resume Next 16 With WorksheetFunction 17 ixTop = .Match(strBegin, rngKey, 0) 18 ixBottom = .Match(strEnd, rngKey, 0) 19 End With 20 On Error GoTo 0 21 22 '転記 23 If ixTop > 0 Then 24 If MsgBox("登録済ですが上書きしますか?", Buttons:=vbYesNo) = vbYes Then 25 Application.Range(rngKey(ixTop), rngKey(ixBottom)).Offset(, 1).Value = "更新" 26 Else 27 MsgBox "キャンセル" 28 End If 29 Else 30 rngKey(rngKey.Count + 1, 2).Resize(ixBottom - ixTop + 1).Value = "新規" 31 End If 32End Sub

こんな感じですかねぇ。。。

でも、こういうデータの記録の仕方をしたら、
変更があった時、変更前のデータをもれなく探すのが困難ではないでしょうか?
かといっていい代案を思いつかないのですが。。。
たぶん、1行で収めちゃうかなぁ。。。。
あぁ、、、できなくはないのかぁ。。。。。
でも、1行に収めたいような気がする。

投稿2020/03/27 09:32

編集2020/03/27 09:34
mattuwan

総合スコア2136

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

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

care_raisu

2020/03/30 02:20

難しい、、、! こんなに見やすく短いコードでできるんですね、、 まだまだ勉強不足な故、使われているものの理解がおいついていません! すごい!しっかりそれらを使えるほどには勉強してきます。 ありがとうございます。
guest

0

ベストアンサー

For Each Tgtnm In Range("E:E")

E列全てをLoopするのはさすがに非効率
あと「txt予定日」「txt帰社日」に日付と判定されない文字列を入れた時のエラー対策とか
かなり先の日付を入力してしまったりした場合に範囲制限するかどうかとか
検討したほうが良いでしょうね

とりあえずセルLoop判定ではなくてMatch関数判定のサンプル

VBA

1Sub btm登録_Click() 2 Dim ws As Worksheet 3 Dim r As Range 4 Dim Date1 As Date 5 Dim Date2 As Date 6 Dim lastRow As Long 7 Dim i As Long 8 Dim key As String 9 Dim x 10 11 Set ws = Worksheets("予定表") 'シートセット 12 lastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row '一番下の行の取得 13 Set r = ws.Range("E1").Resize(lastRow) 14 15 Date1 = txt予定日.Text '例)3/10 16 Date2 = txt帰社日.Text '例)3/13 17 18 For i = 0 To DateDiff("d", Date1, Date2) 19 '検索key文字列をつくり 20 key = CLng(Date1 + i) & txt社員番号.Text 21 'Match関数で登録有無を調べる 22 x = Application.Match(key, r, 0) 23 If IsError(x) Then 24 '無ければ新規 25 With ws.Cells(ws.Rows.Count, 3).End(xlUp) 26 .Offset(1, 0).Value = DateAdd("d", i, Date1) 27 .Offset(1, 1).Value = txt社員番号.Text '例)1234 28 .Offset(1, 2).FormulaR1C1 = "=RC[-2]&RC[-1]" 29 .Offset(1, 3).Value = "新規" 30 .Offset(1, 4).Value = "登録" 31 .Offset(1, 5).Value = "しました" 32 End With 33 Else 34 If MsgBox("登録済ですが上書きしますか?", Buttons:=vbYesNo) = vbYes Then 35 With ws.Cells(x, 6) 36 .Offset(, 0).Value = "上書き" 37 .Offset(, 1).Value = "され" 38 .Offset(, 2).Value = "ました" 39 End With 40 Else 41 MsgBox "入力を終了します" 42 End If 43 End If 44 Next 45End Sub

投稿2020/03/27 09:15

編集2020/03/27 09:30
end-u

総合スコア52

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

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

care_raisu

2020/03/30 02:04

match関数を使うことを思いつきませんでした、、 テキストBOXの方にはカレンダーフォームを設置し、 そこから選んでもらうようにしてはあるので判定されない文字の入力はされないと信じたいのですが かなり先の日付に対しては盲点でしたので 単純ですがIFとmsgboxを使い今日の日付から1か月の入力のみ有効とできるよう設定できるようにします。 また使ったことのない関数がたくさんありますので一度調べてどういう働きをしているのか確認してみます。 大変勉強になりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問