【会員アンケートご協力のお願い】抽選で計5名様に役立つ書籍をプレゼント!
Excel (VBA) |
|
(指定なし : 指定なし)
『SpinButton』に値が上手く入らない??
投稿日時: 24/10/15 13:02:45
投稿者: けけちゃま
|
---|---|
いつもお世話になっております。
Private Sub SpinButton1_Change() TextBox1.Text = Format(SpinButton1.Value, "hh:mm") End Sub Private Sub TextBox1_AfterUpdate() If TextBox1.Text = "" Then Exit Sub End If SpinButton1.Value = CDate(TextBox1.Text) End Sub Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If TextBox1.Text <> "" Then If Not IsDate(TextBox1.Text) Then MsgBox "時間を入力(hh:mm)してください。" Cancel = True TextBox1.Text = Format(Time, "hh:mm") End If End If End Sub '【初期設定】 Private Sub UserForm_Initialize() TextBox1.Text = Format(SpinButton1.Value, "hh:mm") SpinButton1.Min = CDate("00:00:00") SpinButton1.Max = CDate("23:59:59") SpinButton1.Value = Time TextBox1.Text = Format(SpinButton1.Value, "hh:mm") End Sub 私の想定では、これを実行すると、 「Valueプロパティを設定できません」となります。 最初にTextBox1.Textには、システム時間「hh:mm」の形式で表示されるはずだったのですが、 どうも Initialize の SpinButton1.Value = Time の値が「1」なんです。 申し訳ございません。 SpinButton1.Min をどう設定したら起動するか、 どなたかお分かりになられましたら教えていただけますでしょうか・・。 |
投稿日時: 24/10/15 13:04:34
投稿者: けけちゃま
|
|
---|---|
文章訂正です。
|
投稿日時: 24/10/15 16:17:53
投稿者: mattuwan44
|
|
---|---|
スピンボタンのValueプロパティには整数しか設定できません。
|
投稿日時: 24/10/15 22:11:47
投稿者: けけちゃま
|
|
---|---|
mattuwan44様
Option Explicit Dim t As Double Private Sub SpinButton1_Change() TextBox1.Text = Format(TimeSerial(0, SpinButton1.Value, 0), "hh:mm") End Sub Private Sub SpinButton2_AfterUpdate() If TextBox1.Text = "" Then Exit Sub End If SpinButton2.Value = DateDiff("s", 0, TextBox1.Text) End Sub Private Sub SpinButton2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If TextBox1.Text <> "" And Not IsDate(TextBox1.Text) Then MsgBox "時間を入力(hh:mm)してください。" Cancel = True TextBox1.Text = Format(t, "hh:mm") End If End Sub Private Sub SpinButton2_Change() TextBox1.Text = Format(TimeSerial(0, 0, SpinButton2.Value), "hh:mm") End Sub Private Sub TextBox1_AfterUpdate() If TextBox1.Text = "" Then Exit Sub End If SpinButton1.Value = DateDiff("n", 0, TextBox1.Text) End Sub Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If TextBox1.Text <> "" And Not IsDate(TextBox1.Text) Then MsgBox "時間を入力(hh:mm)してください。" Cancel = True TextBox1.Text = Format(t, "hh:mm") End If End Sub '【初期設定】 Private Sub UserForm_Initialize() t = Time TextBox1.Text = Format(t, "hh:mm") SpinButton1.Min = 0 SpinButton1.Max = 23 * 60 '最大23時となり、分に換算すると23*60=1,380分(そして60ずつ増加させる) SpinButton1.SmallChange = 60 SpinButton1.Value = DateDiff("n", 0, t) SpinButton2.Min = 0 SpinButton2.Max = 59 * 60 '最大59分となり、秒に換算すると59*60=3,540秒(そして60ずつ増加させる) SpinButton2.SmallChange = 60 SpinButton2.Value = DateDiff("s", 0, t) |
投稿日時: 24/10/16 08:16:52
投稿者: mattuwan44
|
|
---|---|
難しく考えなくていいですよ。
Option Explicit Private Sub UserForm_Initialize() Dim t As Double: t = Time With Me.SpinButton1 .Min = 0 .Max = 23 .SmallChange = 1 .Value = Hour(t) End With With Me.SpinButton2 .Min = 0 .Max = 59 .SmallChange = 1 .Value = Minute(t) End With Me.TextBox1.Text = GetText End Sub Private Sub SpinButton1_Change() Me.TextBox1.Text = GetText End Sub Private Sub SpinButton2_Change() Me.TextBox1.Text = GetText End Sub Private Function GetText() As String GetText = Me.SpinButton1.Value & ":" & Me.SpinButton2.Value End Function (余分な空白行は読むのに下に長くなって頻繁にスクロールすることになるので、 読みにくくないですか?) |
投稿日時: 24/10/16 08:19:29
投稿者: mattuwan44
|
|
---|---|
あ、分のところ、2桁に固定した方がよみやすいですかね?
|
投稿日時: 24/10/16 14:30:58
投稿者: mattuwan44
|
|
---|---|
Option Explicit Private Sub UserForm_Initialize() With Me.SpinButton1 .Min = 0 .Max = 23 .SmallChange = 1 End With With Me.SpinButton2 .Min = 0 .Max = 59 .SmallChange = 1 End With GetTime End Sub Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim s As Variant Dim d As Date s = Trim(Me.TextBox1.Text) If IsDate(s) Then d = CDate(s) If d < 1 Then GetTime d Exit Sub End If End If If Len(s) = 0 Then GetTime Else With Me.TextBox1 .SelStart = 0 .SelLength = Len(.Text) End With Cancel = True MsgBox "時刻を入力してください。(24:00未満)" End If End Sub Private Sub SpinButton1_Change() Me.TextBox1.Text = GetText End Sub Private Sub SpinButton2_Change() Me.TextBox1.Text = GetText End Sub Private Function GetText() As String GetText = Me.SpinButton1.Value & ":" & Format(Me.SpinButton2.Value, "00") End Function Private Function GetTime(Optional ByVal t As Double = 9999) If t >= 1 Then t = Time Me.SpinButton1.Value = Hour(t) Me.SpinButton2.Value = Minute(t) End Function テキストボックスに手入力も考えてみました。 が、あんまりうまくないです^^; 何時間でも考えてしまうので、これくらいで^^; あ、スピンボタンよりスクロールバーの方が使い勝手が良いかも知れません。 (スライドバーは使えなくなったのかなぁ。。。。) |
投稿日時: 24/10/16 21:59:00
投稿者: けけちゃま
|
|
---|---|
mattuwan44様
Option Explicit Dim t As Double Private Sub TextBox1_AfterUpdate() If TextBox1.Text = "" Then Exit Sub End If SpinButton1.Value = Hour(TextBox1.Text) SpinButton2.Value = Minute(TextBox1.Text) End Sub Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If TextBox1.Text <> "" And Not IsDate(TextBox1.Text) Then MsgBox "時間を入力(hh:mm)してください。" Cancel = True TextBox1.Text = Format(t, "hh:mm") End If End Sub Private Sub UserForm_Initialize() t = Time With Me.SpinButton1 .Min = 0 .Max = 23 .SmallChange = 1 .Value = Hour(t) End With With Me.SpinButton2 .Min = 0 .Max = 59 .SmallChange = 1 .Value = Minute(t) End With Me.TextBox1.Text = GetText End Sub Private Sub SpinButton1_Change() Me.TextBox1.Text = Format(CDate(GetText), "hh:mm") End Sub Private Sub SpinButton2_Change() Me.TextBox1.Text = Format(CDate(GetText), "hh:mm") End Sub Private Function GetText() As String GetText = Me.SpinButton1.Value & ":" & Me.SpinButton2.Value End Function |
投稿日時: 24/10/17 08:00:50
投稿者: mattuwan44
|
|
---|---|
SpinButton1.Value = Hour(TextBox1.Text) SpinButton2.Value = Minute(TextBox1.Text) ↑ちらっと見ただけですが、この辺とか、変数に受けておいてたほうがよいかもです。 テキストボックスを順次書き換えて行ったりするので、 いろいろいじってて、 あえて手入力を用意する必要もないかと思いました。 スピンボタン長押しで変更で十分かなぁと思ったりしました。 |
投稿日時: 24/10/17 20:41:46
投稿者: mattuwan44
|
|
---|---|
Option Explicit Private Sub UserForm_Initialize() With Me.SpinButton1 .Min = 0 .Max = 23 .SmallChange = 1 End With With Me.SpinButton2 .Min = 0 .Max = 59 .SmallChange = 1 End With Dim d As Date: d = Time Me.TextBox1.Text = Format(d, "hh:nn") SetSpinValue d End Sub Private Sub TextBox1_Enter() With Me.TextBox1 .IMEMode = fmIMEModeDisable End With End Sub Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) If Chr(KeyAscii) Like "[!0-9:]" Then KeyAscii = 0 End If End Sub Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim d As Variant With Me.TextBox1 d = .Text If IsDate(d) Then d = CDate(d) If d < 1 Then .Text = Format(d, "hh:nn") SetSpinValue d Exit Sub End If End If .SelStart = 0 .SelLength = Len(.Text) End With Beep Cancel = True End Sub Private Sub SetSpinValue(ByVal d As Date) Application.EnableEvents = False Me.SpinButton1.Value = Hour(d) Me.SpinButton2.Value = Minute(d) Application.EnableEvents = True End Sub Private Sub SpinButton1_Change() SetSpin2Text End Sub Private Sub SpinButton2_Change() SetSpin2Text End Sub Private Sub SetSpin2Text() Me.TextBox1.Text = Format(Me.SpinButton1.Value, "00") _ & ":" & Format(Me.SpinButton2.Value, "00") End Sub 時間が出来ると気になって考えてしまいますね^^; こんな感じでいかがでしょう? やっぱテキストボックスに手入力だとどうしてもミスタイプを制御しきれないので、 スピンボタンのみで入力がよいように思います。 あと、メッセージボックスを表示すると、 時刻でない文字を入力しかけて×ボタンで閉じようとしたときに、 メッセージが表示されて美しくないです。 なにか方法があるかも知れませんが、 本当にメッセージが必要かどうか疑問なので、 なくてもよいかと思いました。 >実行時の時間が21:55として、手入力で15:00にすると、15:55になるんです 少しデバッグしてみましたが、やはり、 SpinButton1.Value = Hour(TextBox1.Text) SpinButton2.Value = Minute(TextBox1.Text) ここがまずいです。 dim t as date t = time SpinButton1.Value = Hour(t) SpinButton2.Value = Minute(t) というような形で、変数を用いないと変なことになります。 |
投稿日時: 24/10/17 21:28:59
投稿者: けけちゃま
|
|
---|---|
mattuwan441様
Option Explicit Dim t As Double Private Sub SpinButton2_Change() TextBox1.Text = Format(TimeSerial(0, SpinButton2.Value, 0), "hh:mm") End Sub Private Sub TextBox1_AfterUpdate() If TextBox1.Text = "" Then Exit Sub End If SpinButton2.Value = DateDiff("n", 0, TextBox1.Text) End Sub Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) If TextBox1.Text <> "" And Not IsDate(TextBox1.Text) Then MsgBox "時間を入力(hh:mm)してください。" Cancel = True TextBox1.Text = Format(t, "hh:mm") End If End Sub '【初期設定】 Private Sub UserForm_Initialize() t = Time TextBox1.Text = Format(t, "hh:mm") SpinButton2.Min = 0 SpinButton2.Max = 23 * 60 '最大23:59となり、分に換算すると23*60=1,380分(そして1ずつ増加させる) SpinButton2.SmallChange = 1 Debug.Print t Debug.Print DateDiff("n", 0, t) SpinButton2.Value = DateDiff("n", 0, t) End Sub 【私的結論2】ABであれば mattuwan44様が2回目にいただいた方法で可能。 【私的結論3】@ABとなると、ほぼ不可能(多分、できなくはないが、結論1や結論2に比べるとかなりコードも長くなり複雑化してしまう。 ということでした。 そして20:41のmattuwan44様の回答みて、やはり私の脳みそのキャパを超えた複雑なコードでした爆。(Change Initialize AfterUpdate BeforeUpdate 以外はまだほど未知の領域)。 でも、この回答については後程また、じっくり理解に努めますので、本当にありがとうございます…泣 また、この3つ結論はあながち間違っていないとわかっただけでも、とても大きな収穫でした! 一旦、これで解決にさせていただきたいと思います。 そのまえになのですが、あと1個だけ聞いてもいいですか。 質問とはそれてしまうのですが、 mattuwan44様のコードに「Me.」ってあると思うのですが、フォームモジュールの時って、特にMe.がなくても、バグを起こす(別のフォームやエクセルからデータを間違ってとることはない)ことはないと思うので、書かなくてもいいと勝手に思っているのですが、あえて書かれている理由があれば教えていただけますか?!(私の勉強不足・知識不足かもしれませんがTT) |
投稿日時: 24/10/18 07:39:31
投稿者: mattuwan44
|
|
---|---|
>特にMe.がなくても、バグを起こす(別のフォームやエクセルからデータを間違ってとることはない)ことはないと思うので、書かなくてもいい
|
投稿日時: 24/10/18 19:53:01
投稿者: mattuwan44
|
|
---|---|
ああああ。。。
|
投稿日時: 24/10/19 08:58:47
投稿者: mattuwan44
|
|
---|---|
時間があるようなので、、、
Option Explicit Private Sub UserForm_Initialize() Dim t As Date: t = Time '※各オブジェクトのプロパティは事前に設定済とする。 Me.SpinButton1.Value = Hour(t) Me.SpinButton2.Value = Minute(t) End Sub Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim s As String: s = Me.TextBox1.Text Dim e As Long 'とりあえずスピンボタンに値を設定してみる On Error Resume Next Application.EnableEvents = False Me.SpinButton1.Value = CLng(s) Application.EnableEvents = True e = Err.Number On Error GoTo 0 'エラーならキャンセルをして再入力を促す If e <> 0 Then With Me.TextBox1 .SelStart = 0 .SelLength = Len(s) End With Cancel = True End If End Sub Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim s As String: s = Me.TextBox2.Text Dim e As Long On Error Resume Next Application.EnableEvents = False Me.SpinButton2.Value = CLng(s) Application.EnableEvents = True e = Err.Number On Error GoTo 0 If e <> 0 Then With Me.TextBox2 .SelStart = 0 .SelLength = Len(s) End With Cancel = True End If End Sub Private Sub SpinButton1_Change() Me.TextBox1.Text = Format(Me.SpinButton1.Value, "00") End Sub Private Sub SpinButton2_Change() Me.TextBox2.Text = Format(Me.SpinButton2.Value, "00") End Sub 各コントロールのプロパティは事前にプロパティボックスで 設定してデザインを含め作り込むとよいかと思います。 TextBox2のプロパティの設定の例> BackStyle:0-fmBackStyeleTransparrent ’背景を透明に Font:サイズ 12 ’老眼にも優しく大きめに IMEMode:3-fmIMEModeDisable ’入力モードを半角英数に Left:42 ’表示位置を微調整 MaxLength:2 '入力文字数制限 specialEffect:0-fmspecialEffectFlat ’見た目をフラットに Text:00 '初期の文字列(見た目を確認するため入力) Top:43 ’表示位置を微調整 分からない単語は、ヘルプや、Webサイトを調べてみてください。 わたしも丸覚えしているわけではなく、 ヘルプとか見ながら思い出しながら、そして、試しながら、 書いています。 同じようなコードが2回づつ出てくるので、 まとめるなら、クラスモジュールの勉強が必要になりますが、 使う人には関係ない話ですので、動作に不満がなければ、 これくらいの感じでもいいかと思います。 のちのちのメンテナンス性を気にするなら、 クラスモジュールの勉強をしてみてください。 |
投稿日時: 24/10/21 21:48:53
投稿者: けけちゃま
|
|
---|---|
mattuwan44様
|