EXCELのVBAを使って経費の打ち込みをするマクロを作っています
その中で、コンボボックスで日付を選択するようにしました
コンボボックスに表示する日付はセルから「RowSource」で取り出しました
セルの日付の入力形式は「2008/10/1」です
そのセルの書式設定で表示形式を「ユーザー定義で d (日だけ表示)」としています
なので、コンボボックスで選択して表示する際も日だけを表示したいのですがうまくいきません
ComboBox1 = Format(ComboBox1, "d")
とすると、コンボボックス内で数字がちらちらしてランダムに数字が表示されてしまいます
ComboBox1 = Format(ComboBox1, "m月d日")
この形だと、きちんと「10月1日」の様に表示されます
Private Sub UserForm_Initialize()
With ComboBox1
.RowSource = "sheet1!A1:A5" '日付のセル
End With
End Sub
Private Sub ComboBox1_Change()
ComboBox1 = Format(ComboBox1, "m月d日")
End Sub
日だけを表示する方法をご教授ください
No.1
- 回答日時:
下記のようにすればいいようです。
ComboBox1.Value = Format(ComboBox1.Value, "d""日""")
早速のご回答ありがとうございます!
この場合「○○日」のように表示されますよね?
2008/10/1であれば「1日」と。
この形はうまくいきました。
今回はできれば数字だけ表示したいのですが。
「1」のようにしたいのです。
「ComboBox1.Value = Format(ComboBox1.Value, "d")」とすると、マクロが変な動きをする(選択した日+13で表示する)ので、解決策か別の方法を教えていただけないでしょうか。
よろしくお願いします。
No.2
- 回答日時:
質問者のやり方に現状のエクセルVBAでは無理があるように思った。
(1)セルsheet1!A1:A5の書式を、エクセルのシートの機能の書式で「d」としておくと、コンボのドロップダウンのアイテムの表示も日数字にの1,2,3・・になること。
(2)しかしアイテムの1つを選択したとき、ボックスには、何もしないと日付シリアル値の数字が表示される。例39xxx
(3)シートのセルに、選択したアイテムを表示するときは、コンボボックスの値を数値化して= Val(ComboBox1)、そのセルの書式を日付の表示形式にしておくと2008/9/3のように表示され、セルの値も日付シリアル値になって、後には日付としてそのまま使える。
日付シリアル値は数値であり、コンボやテキストボックスは文字列を返すのでVALはやむを得ないと思う。
ーー
問題はコンボで選択したときコンボに表示されるものを、日数字だけにする仕組みは無いのではないかな。
コンボに、エクセルシートでは出来る、日付のフォーマットを設定するプロパティが見当たらないから。(注)
もしFormat関数でコンボボックスの値を、日だけ表示すると、連結するセルに値(日付)をセットするときに、何年+何月を添えて、日付に再構成しなくてはならないのではないか。
それならコンボは、日数字だけ選択させるほうがすっきりする。
良く年、月、日を独立したコンボて選択させている仕組みをWEBなどで見かける。
ーー
それと_Change()イベントは注意しないと、コンボにプログラムで値をセットすると、_Change()イベントが起こり、ぐるぐる回りになって
おかしくなる場合があるので使用は慎重に。
それ対しては、Application.EnableEvents = Falseが使える場合がある。
ーー
上記(注)の部分は100%は自信はないが、上記で私が言っていることは判ってもらえるでしょうか。
回答してくださりありがとうございます!
>日付のフォーマットを設定するプロパティが見当たらない
私も正攻法の仕方があるのではないかと調べてみたのですが見当たりませんでした。
何も設定しないとシリアル値が出るので、何とかしたいと思うのですが。
なぜ、日付にこだわるかというと月ごとに日付が増減して表示されるようにしているからです。
質問ではマクロの一部を簡略化して載せたので、まだ未完成な全文を載せておきます。
Private Sub UserForm_Initialize()
Dim ws As Worksheet
With ComboBox1
.ColumnCount = -1
.ColumnWidths = -1
.RowSource = "sheet1!A5:A35" '日付のセルを選択
End With
Set ws = Sheets("Sheet1")
With Me.ComboBox2
.Column = ws.Range("S3", ws.Cells(3, Columns.Count).End(xlToLeft)).Value '横列の項目を選択
End With
Set ws = Nothing
End Sub
Private Sub CommandButton1_Click()
Dim ctrl As Control, tst1 As String, txt2 As String
Dim ws As Worksheet, r As Long, c As Long
Set ws = Sheets("sheet1")
For Each ctrl In Me.Controls
Select Case ctrl.Name
Case "ComboBox1", "ComboBox2", "TextBox1"
If Me.Controls(ctrl.Name).Value = "" Then
txt1 = txt1 & ctrl.Name & vbLf
Else
txt2 = txt2 & Me.Controls(ctrl.Name).Value & vbLf
End If
End Select
Next
If Len(txt1) > 0 Then
MsgBox "以下の値を入力してください" & vbLf & txt1, vbExclamation
Exit Sub
Else
ret = MsgBox("以下の値を入力します" & vbLf & txt2, vbOKCancel)
If ret <> vbOK Then Exit Sub
r = Me.ComboBox1.ListIndex + 5
c = Me.ComboBox2.ListIndex + 19
ws.Cells(r, c) = Me.TextBox1.Text 'テキストボックスの内容を選択したセルへ入れる
End If
Set ws = Nothing
End Sub
Private Sub ComboBox1_Change()
ComboBox1 = Format(ComboBox1, "d") 'ココが問題の部分です
End Sub
問題の部分を "m月d日"
とし
日付のセルの表示形式を○月○日の形にするとテキストボックスの値を入力するセルをきちんと選択できます。
しかし、セルの表示形式を d とするとうまくいかないので、コンボボックスの表示形式も d の形にそろえてみようとしています。
No.3
- 回答日時:
こんにちは。
以下のように変更してみてください。
Dim eFlg As Boolean
Private Sub UserForm_Initialize()
With ComboBox1
.RowSource = "sheet1!A1:A5" '日付のセル
End With
End Sub
Private Sub ComboBox1_Change()
If eFlg = False Then
eFlg = True
ComboBox1 = Format(ComboBox1, "d") 'ここでイベントが発生するので
'1回のみ処理出来るように制御が必要
eFlg = False
End If
Application.EnableEvents = True
End Sub
'又は
Private Sub ComboBox1_Click()
ComboBox1 = Format(ComboBox1, "d")
End Sub
ご回答ありがとうございます!
回答してくださった内容を使用してみましたが残念ながら最初と同じ結果になってしまいました。
コンボボックスのマクロが何度も働いているようです。
私の理解不足かもしれませんが今回この方法はうまくいきませんでした…。
しかし、貴重な回答をありがとうございました。
No.4
- 回答日時:
こんにちは
ComboBoxの.Valueを変更すれば、
再び_Changeイベントが発生します。
原理的には無限ループ
(無限ネスト?というか循環参照に近い状態)
が起きています。
□現状を活かすとすれば、
◆ ComboBox1_Change イベントの再帰的な呼び出し
を(一度だけで)抜ける方法として、
Private Sub ComboBox1_Change()
Static flg As Boolean
If Not flg Then
flg = True
With ComboBox1
.Value = Format(.Value, "d")
End With
flg = False
End If
End Sub
ただ、個人的には、こういう方法は選ばないと思います。
なんとなく、手数の割りに安心出来ないような気が、、、
蛇足ですが、本件に Application.EnableEvents は無関係です。
他、
□UserForm Load後の 参照元のセルの値変更を無視できるなら、
(或いは、ComboBox1 の .List をUpdateするプログラムを別に用意するとして)
_Change イベントに依らない方法として、.RowSourceは指定せずに、
◆別解1、
ComboBox1 のリストが最初から「日にちのみ」でも構わないなら、
Private Sub UserForm_Initialize()
Dim vA
vA = Worksheets("Sheet1").Range("A1:A5").Value
vA = Application.Text(vA, "d")
ComboBox1.List = vA
End Sub
・ バリアント型の変数vAに、Sheet1!A1:A5 の値を配列として格納し、
・ vAを一括で String型の「日にちのみ」に変換し(ワークシート関数のTEXTを使用)、
・ ComboBox1 の .List プロパティーに、配列としての vA を代入。
◆別解2、
ComboBox1 のリストを2列にして、選択するリストの表示は通常の日付、
.Valueの戻り値は「日にちのみ」にする方法として、
リストの1列目は年月日、2列目は「日にちのみ」にしておく。
Private Sub UserForm_Initialize()
Dim vA
Dim i As Integer
vA = Worksheets("Sheet1").Range("A1:A5").Value
ReDim Preserve vA(1 To 5, 1 To 2)
For i = 1 To 5
vA(i, 2) = Day(vA(i, 1))
Next
ComboBox1.List = vA
ComboBox1.TextColumn = 2
End Sub
・ バリアント型の変数vAに、Sheet1!A1:A5 の値を配列として格納し、
・ vAの(値を変えずに)サイズを2列に変更して、
・ vAの2列めに「日にちのみ」を格納し、
・ ComboBox1 の .List プロパティーに、配列としての vA を代入。
・ .List の 2列めが .Valueになるように指定。
という方法もあります。
この(2列にした)場合は、_Change イベント内などで、
ret = ComboBox1.List(ComboBox1.ListIndex, 0) * 1
とすれば、シリアル値に戻すこともできます(この場合はVal関数は難あり)。
□実行時の手数を減らす意味では、
UserForm_Initialize は ご提示(.RowSource)のままで、
◆ComboBox(または ListBox)に 「日にちのみ」のリストを表示させて、
_Changeイベントから
表示用に隣接させた TestBox(または Label)の .Value(.Caption)を
操作する手も考えられるでしょうか。(同時にListBoxを非表示にするなど)
(Controlが増えることに若干抵抗はあるけれど)
.RowSource
を指定する場合は、参照される側のセル(日付型)の
「表示」(.Listへ)
と
「値」 (,Valueへ)
のそれぞれが反映されるようで、
その点の混乱を解消するには、.Listプロパティーに
「値」(配列)を直接指定する必要があるようですね。
この混乱のことを問題にされているように受けての回答でした。
一番すっきりさせる方法としては、参照される側のセルの値を
整数型にしておく方法かとも思うのですが、、、
ご回答ありがとうございます!
おっしゃる通りコンボボックスで無限ループにはまっているようでした。
ComboBox1_Change()のところを、「一度だけで抜ける方法」で解決することができました。
別解1でもうまくいきました。
今のところ別解1を採用させていただこうかと思います。
別解2ですが、5行だとうまくいくのですが、知識不足で、一月分の31行にするときにどこを変更すればよいか分からず31行では試せませんでした…
この方法も面白いので試してみたいと思うのですが。
ちなみに、表示される日付は2008/9/1の形から9月1日等の表示に変えることができるのでしょうか?
よければおしえてください。
cj_moverさんの回答でうまく解決できそうです。
ありがとうございました。
このあとさらに付け加えていこうと思っています。
選択したセルに数値が入っている場合は、その数値にテキストボックスの数値を加算するようにしたいと思っています。
また分からないときには新しい質問で質問させてください。
よろしくお願いいたします。
No.5ベストアンサー
- 回答日時:
こんにちは、#4です。
ご丁寧なレスをどうも。
えーと、、、
ComboBox から シリアル値を返す必要はないようですね。
〉別解2ですが、5行だとうまくいくのですが、知識不足で、一月分の31行にするときにどこを変更すればよいか分からず31行では試せませんでした…
〉この方法も面白いので試してみたいと思うのですが。
〉ちなみに、表示される日付は2008/9/1の形から9月1日等の表示に変えることができるのでしょうか?
"一月分の31行"ということは、
日付型の値で、「日にちのみ」が表示されたセルが、
月の初め(1日)から末日まで、連続(欠落なく)して
A5:A35(または、A5:A32、A5:A34)の範囲にある、
ということですよね?
◆別解2、改、
ComboBox1 のリストを2列にして、
選択するリストの表示は「m 月 d 日」、
選択後の.Value(.Text)は「日にちのみ」にする
(※シリアル値が必要な場合は、合成することになります)
(一応、締め日がズレても[26日から翌25日とか]対応する筈です)
Private Sub UserForm_Initialize()
Dim vA
Dim i As Integer
Dim dpm
' ' 当月の日数を求める
dpm = Worksheets("Sheet1").Range("A5").Value
dpm = Day(DateSerial(Year(dpm), Month(dpm) + 1, 1) - 1)
' ' A5から下へ当月の日数分の範囲の値をバリアント型の変数vAに格納(内部的にDate型)
vA = Worksheets("Sheet1").Range("A5:A" & dpm + 4).Value
' ' vAを一括で String型の「m 月 d 日」に変換(ワークシート関数のTEXTを使用)
vA = Application.Text(vA, "m"" 月 ""d"" 日""")
ReDim Preserve vA(1 To dpm, 1 To 2)
For i = 1 To dpm
vA(i, 2) = Day(vA(i, 1))
' ' vA(i, 2) = i ' でいいのかも?
Next i
ComboBox1.List = vA
ComboBox1.TextColumn = 2
End Sub
一応、お尋ねの答えとしては、上のようになります。
(A列に誤(未)入力がある場合をケアしていません。)
1ヶ月分の日付を文字列にしたもの(「日にちのみ」と「m 月 d 日」)をリストにするのなら、
セル範囲にある日付を追いかけなくてもいいような気もしますね(^^;)。
◆別解2、改、改、
わざわざ書くほどでもありませんけど、、、
(こちらは、1日から末日、専用)
Private Sub UserForm_Initialize()
Dim dpm
Dim m As Long
Dim vA
Dim i As Integer
dpm = Worksheets("Sheet1").Range("A5").Value
m = Month(dpm)
dpm = Day(DateSerial(Year(dpm), m + 1, 1) - 1)
ReDim vA(1 To dpm, 1 To 2)
For i = 1 To dpm
vA(i, 1) = m & " 月 " & i & " 日 "
vA(i, 2) = i
Next i
ComboBox1.List = vA
ComboBox1.TextColumn = 2
End Sub
それでは、また
参考URL:http://www.clayhouse.jp/array/array.htm
詳しく教えてくださり感謝します。
dpm = Day(DateSerial(Year(dpm), Month(dpm) + 1, 1) - 1)
で、マクロを使ってその月の日数をもとめることができるんですね。
今までマクロを使っていないときは29日~31日のセルを関数で
=IF(DAY(A32+1)<>29,"",A32+1)
=IF(DAY(A32+2)<>30,"",A32+2)
=IF(DAY(A32+3)<>31,"",A32+3)
として、無い月はセルに表示しないようにしていました。
なのでコンボボックスで日を表示するときもセルの関数で表示しないというのをそのまま利用していましたが、マクロでその月の日数を数えれるのはいいですね。
VBAについてはまだまだ初心者なので回答していただいた内容で解読できていないところもあるので、理解できるようにもう少し勉強してみたいと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA。複数のChangeイベントをまとめる方法 2 2022/03/31 12:03
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/01/23 11:02
- Visual Basic(VBA) VBA ComboBoxについて 2 2022/10/21 12:15
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2023/01/23 17:13
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/01/23 09:24
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2023/05/23 16:28
- その他(ギャンブル) BOって何歳でも始めれるんですか?当たる確率的には競馬より全然高い50%とかなんですか? 2 2022/09/06 15:13
- Excel(エクセル) エクセルについて教えてください。 1 2022/12/26 09:01
- Visual Basic(VBA) エクセルのマクロについて教えてください。 3 2023/02/17 11:59
- Excel(エクセル) エクセルについて教えてください。 1 2023/03/03 08:38
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
VBA コンボボックスの表示(日付)について
Visual Basic(VBA)
-
エクセルVBA ユーザーフォームのTextBoxを日付にしたい
Excel(エクセル)
-
コンボボックス内の文字サイズ変更
Excel(エクセル)
-
-
4
UserForm1.Showでエラーになります。
工学
-
5
エクセルVBAでテキストボックスに入力があった場合のみ、ワークシートに転記したい
Visual Basic(VBA)
-
6
Excelにて、ユーザーフォームで、日付けの範囲を指定し、検索しデーターを抽出し 別シートへ転記した
Excel(エクセル)
-
7
コンボボックス で年月を選ぶ方法
Excel(エクセル)
-
8
VBAのコマンドボタンの文字列の改行方法は?
Visual Basic(VBA)
-
9
エクセルVBA テキストボックスに3桁ごとにコンマ
Visual Basic(VBA)
-
10
excelVBA コンボボックスに時刻で表示したい
Excel(エクセル)
-
11
コンボボックスに日付を表示する
Visual Basic(VBA)
-
12
VBA フォームのテキストボックスにセルの値を表示させたいが改行していたら改行もあわせて表示させたい
Excel(エクセル)
-
13
EXCEL・VBAフォームの日付(表示形式を変更したい)
Excel(エクセル)
-
14
VBAでユーザーフォームを再表示させたい。
Excel(エクセル)
-
15
コンボボックスにdateで取得した月の日数分を表示したい
Visual Basic(VBA)
-
16
EXCEL VBAで全選択範囲の解除
Excel(エクセル)
-
17
コンボボックスにリストが表示されません・・・
Excel(エクセル)
-
18
エクセルVBA テキストボックスへのセットフォーカスについて
Visual Basic(VBA)
-
19
EXCEL VBA 指定したファイルが存在しない場合メッセージボックスを表示させる
Access(アクセス)
-
20
EXCELのコンボボックス 配置の縦位置の変更はどうすれば?
Windows Vista・XP
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
首吊りどこ締めるの
-
至急!尿検査前日にオナニーし...
-
尿検査前日に自慰行為した時の...
-
白血球が多いとどんな心配があ...
-
尿検査の前日は自慰控えたほう...
-
検便についてです。 便は取れた...
-
彼女のことが好きすぎて彼女の...
-
勃起する時って痛いんですか? ...
-
EXCELで条件付き書式で空白セル...
-
腕を見たら黄色くなってる部分...
-
EXCELで式からグラフを描くには?
-
変な話しになります。尿検査で...
-
excelでsin二乗のやり方を教え...
-
エクセル指定した範囲からラン...
-
Excelで""で囲む方法
-
ある範囲のセルから任意の値を...
-
2つの数値のうち、数値が小さい...
-
精子が黄色?
-
エクセルでエラーが出て困って...
-
納豆食べた後の尿の納豆臭は何故?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
至急!尿検査前日にオナニーし...
-
首吊りどこ締めるの
-
尿検査の前日は自慰控えたほう...
-
尿検査前日に自慰行為した時の...
-
検便についてです。 便は取れた...
-
白血球が多いとどんな心配があ...
-
中出しをするとお腹が痛い・・・。
-
射精をして1週間以内に尿検査を...
-
彼女のことが好きすぎて彼女の...
-
腕を見たら黄色くなってる部分...
-
勃起する時って痛いんですか? ...
-
変な話しになります。尿検査で...
-
これって喉仏ですか? 私は女性...
-
EXCELで条件付き書式で空白セル...
-
男です。昨日の午後3時くらいに...
-
今朝、毎朝の習慣でオナニーし...
-
納豆食べた後の尿の納豆臭は何故?
-
1日前の検尿
-
値が入っているときだけ計算結...
-
精子が黄色?
おすすめ情報