Excel VBAについて

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:03/06/01 23:56
>951
たしかVBAはコントロール配列を作れなかったから無理
953951:03/06/02 07:42
>952
やはりそうですか。
Controls("Textbox" & i) のような擬似コントロール配列も
このような場合には使えないし。どうしてVBと共通の仕様に
しないのやら・・・
コントロール配列ってなんでつか?なにができるのでつか?
>>954
文字通り、コントロールの配列です。

同じ属性を持つコントロールを配列で管理すれば、コーディングの時に何かと
便利です。

例えばコントロールが10個あった場合、VBAの場合10個全てにユニークな
名前を付ける必要がありますが、VBの場合はコントロールを配列にすることで、
一つの名前で扱うことができます。

これにより、本来10個分のコードを書く手間を省略する事が可能になり、コードの
メンテナンス性が向上します(使い方によっては逆になる場合もある。そのへんの
事情は配列変数と同様)。

同じ属性のコントロールを一元に扱えるということは、イベントもまた一元に扱える
という事で、例えばコントロール配列Aに定義したイベントは、その要素である
A(1)、A(2)…に対しても、同じように作用します。952の回答は、これがVBAでは
出来ないという事を意味しているのです。
VB.NETでは無くなったけどね
957デフォルトの名無しさん:03/06/02 11:13
>>956
へー、じゃぁどうやるの?ってすれ違いかな
Visual Basic .NET と Visual C# .NET におけるコントロール配列の作成
http://www.microsoft.com/japan/msdn/vs/general/vbtchCreatingControlArraysInVisualBasicNETVisualCNET.asp
>>951
調べてみたところ、ユーザー定義クラスを利用すれば出来ないこともないらしい。
以下テキストボックスが5個の場合の例。

'UserFormのモジュールに書くコード
Option Explicit
Option Base 1

Dim myClass1(5) As New Class1
Private Sub UserForm_Initialize()
  Dim myTextbox As New Collection
  Dim i As Integer
  With myTextbox
    .Add Item:=TextBox1
    .Add Item:=TextBox2
    .Add Item:=TextBox3
    .Add Item:=TextBox4
    .Add Item:=TextBox5
  End With

  For i = 1 To 5
    Set myClass1(i) = New Class1
    With myClass1(i)
      .txt = myTextbox(i)
      .Index = i
    End With
  Next
End Sub
'Class1モジュールに書くコード
Option Explicit

Private WithEvents myTxt As MSForms.TextBox
Private idx As Integer
Public Property Get txt() As MSForms.TextBox
  Set txt = myTxt
End Property
Public Property Let txt(ByVal txtNew As MSForms.TextBox)
  Set myTxt = txtNew
End Property
Public Property Get Index() As Integer
  Index = idx
End Property
Public Property Let Index(ByVal idxNew As Integer)
  idx = idxNew
End Property
Private Sub myTxt_Change()
  MsgBox "textbox(" & idx & ")を変更しました"
End Sub

このコードを使うと、テキストボックスを変更した際にChangeイベントが発生し、
メッセージボックスにテキストボックスコレクションのインデックス値が表示される。

ただ自分が試した限りでは、何故かExitイベントが発生しないのだが、原因は
私の力不足により不明です。申し訳ない。
961デフォルトの名無しさん:03/06/02 19:52
Javaでクラスに慣れ親しんだ後に、VBでクラスを組むと気持ち悪い。
中途半端だし。更に、VBAはCollection使わないと凝ったことは何一つできないという罠。
可変長配列の代替としてCollection使うのは良いことだ。可読性UPするしな。
962預言者:03/06/02 21:38
963951:03/06/02 22:47
>>959
おお、これなら確かにちゃんと動作しますね。
しかしなぜExitイベントだと動作しないのか・・・謎です。
今までクラスモジュールは触ったことがなかったのですが、
使いこなせれば色々と便利なことができそうですね。
959さん、どうもありがとうございました。
>>963
VB/VBAのクラスはオブジェクト指向のクラスとしては足りない機能がおおいけど、
むしろイベント制御用として割り切って使うこともいいんでは
Excel/VBAでコードを書いてて、ちょいとわからなくなったことがあったので
ヘルプを見ようと思って開いたら、すべての項目がなくなってました・・・
これは、再インストール以外に解決策はあるのでしょうか?
>>965
俺だったら真っ先に再インストールするね。
何か事情があるなら無理かも知れんけど。
質問です。
Excel2000で印刷の用紙サイズをB4やB5に設定するとき
PageSetup.PageSize に xlPaperB4 または xlPaperB5 と設定しますが、
OKI ML2030N ではエラーが発生します。

マクロの記録で調べたところ、OKI ML2030N では
B4/B5の設定値が xlPaperB4 や xlPaperB5 ではなくて
122 と 127 になっていました。
この値はプログラムからはどのようにして調べるのでしょうか?

はじめまして、VBA3日目の初心者です。

====================
Sub

A()

End Sub
--------------------
Function A
     ???
End Function
=======================

関数の???ところでエクセルを終了させずにマクロ全体から抜ける方法がわかりません。
今のところ、関数AからBool値をSubに戻して判別してるんですが、
何か便利な関数があるはずだと思うのです。
ヘルプ探したのですが、見つかりませんでした。
もしよろしければおしえていただけませんか?よろしくお願いします。
>>968
Exit Function
ちゃんとヘルプ嫁
どうもです。
いやー、てっきりExit Functionでは関数から抜けるだけだと思ってました。
マクロからも抜けれるんですね。
早速試してみます。
>>968

やっぱだめでした。関数から抜けるだけでした。
探してるものは、いわばFunctionの中でつかえる、Exit Subなんですが。
972969:03/06/06 08:24
>>971
End

マクロ全体から抜けるなどという概念がなくてな
>>972
思ったとおりにいけました。どうもありがとうございました。
Range の CopyFromRecordset メソッドで Range のある Worksheet では
なくて ActiveSheet の Range の位置の NumberFormatLocal が変わって
しまうというバグを見つけたんだが、こんなデカいバグがパッチ当てられて
いないほど DAO って使われてないのか?
975一応テストコード:03/06/07 02:09
Sub test()
Dim dbnam As String
dbnam = ThisWorkbook.FullName & ".dbo"
If Dir(dbnam) <> "" Then Kill dbnam
Dim db As Database
Set db = DBEngine.CreateDatabase(dbnam, dbLangGeneral)
Dim table As TableDef
Set table = db.CreateTableDef("data")
table.Fields.Append table.CreateField("date", dbDate)
db.TableDefs.Append table
db.Execute "insert into data values ('2003/06/01')"
db.Execute "insert into data values ('2003/06/02')"
db.Execute "insert into data values ('2003/06/03')"
Dim rs As Recordset
Set rs = db.OpenRecordset("select * from data")
Dim ws As Worksheet
Set ws = ActiveSheet
Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets.Add
ws.Activate
ws.Cells(1, 1).NumberFormatLocal = "G/標準"
ws.Cells(1, 2).NumberFormatLocal = "G/標準"
ws.Cells(1, 3).NumberFormatLocal = "G/標準"
wsData.Range("a1").CopyFromRecordset rs
Application.DisplayAlerts = False
wsData.Delete
Application.DisplayAlerts = True
Debug.Print ws.Cells(1, 1).NumberFormatLocal
Debug.Print ws.Cells(1, 1).NumberFormatLocal
Debug.Print ws.Cells(1, 1).NumberFormatLocal
End Sub
あ、バージョンは97と2000と2002 (10.2614.2625) で確認。

参った・・・一応、CopyFromRecordset の実行中だけ Activate でデータの
シートを ActiveSheet にしたら問題は回避できることは確認した。
でも、今まで気付かずに使いまくり・・・
あー確かに。

仕様と言い張るにはちょっと苦しい動作ですね。
なんかね、曜日を求めるプログラムってよくあるじゃないですか
でね、俺もちょっとやってみようと思ったんだけどサンプルのソース通りにコーディングしたのにコンパイルできないんですよ
↓のソースってどこが間違ってるんですかねぇ〜
ちなみにエラーメッセージは"Sub または Functionが定義されていません"だって。何のことやら
やべぇ、ソース長すぎて書けないんで分割して書きます

Private Sub CommandButton1_Click()
Dim mt(12) As Integer
mt(1) = 31: mt(2) = 28: mt(3) = 31: mt(4) = 30
mt(5) = 31: mt(6) = 30: mt(7) = 31: mt(8) = 31
mt(9) = 30: mt(10) = 31: mt(11) = 30: mt(12) = 31
y = Val(TextBox1.Text)
m = Val(TextBox.Text)
d = Val(TextBox.Text)
If (y Mod 4) = 0 And (y Mod 100) <> 0 Or (y Mod 400) = o Then
mt(2) = 29
Else
mt(2) = 28
End If
zure = y + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400
days = 0
For k = 1 To m - 1
days = days + mk(k)
Next k
week = (zure + days + d - 1) Mod 7
If week = 0 Then
TextBox4.Text = "Sunday"
ElseIf week = 1 Then
TextBox4.Text = "Monday"
ElseIf week = 2 Then
TextBox4.Text = "Tuesday"
ElseIf week = 3 Then
TextBox4.Text = "Wednesday"
ElseIf week = 4 Then
TextBox4.Text = "Thursday"
ElseIf week = 5 Then
TextBox4.Text = "Friday"
ElseIf week = 6 Then
TextBox4.Text = "Saturday"
Else
TextBox4.Text = "Error"
End If
End Sub
982デフォルトの名無しさん:03/06/09 14:53
>>978
どこでエラーが出ているのかな

オレだったらこんなコードにする。
Private Sub CommandButton1_Click()
Dim strWeekday()
strWeekday = Array("", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
If IsDate(Me.TextBox1.Value) = False Then
MsgBox "日付が誤っています。"
Me.TextBox1.SetFocus
Exit Sub
End If
If (Me.TextBox1.Value <> Format(Me.TextBox1.Value, "yyyy/mm/dd")) And _
(Me.TextBox1.Value <> Format(Me.TextBox1.Value, "yyyy/m/d")) Then
MsgBox "日付が誤っています。"
Me.TextBox1.SetFocus
Exit Sub
End If
MsgBox strWeekday(Weekday(Me.TextBox1.Value))
End Sub
983デフォルトの名無しさん:03/06/09 16:05
>>978
日本語のエラーメッセージもわからんのか?
984:03/06/09 16:58
死ねよ
>>984
正論だろ

親切にmkという関数は定義されていませんよと反転付きで教えてくれてるのに
>>985
どこを直せばいいのかきちんと書け
そして死ね
だから反転してるところだって
どう直せばいいのかと聞いてるんだ
死ねよ低脳
>>978
まず、先頭に以下のコードを追加してコンパイルしろ
Option Explicit
990デフォルトの名無しさん:03/06/09 19:06
変数mとdに同じテキストボックスの値を代入したり、
y Mod 400と変数oを比較したり、
突っ込みどころ満載だな、釣りですか?
991 :03/06/09 19:06
>>988
えっれーでかい態度 (w
>>989
コンパイルエラー 修正候補:ステートメントの最後だとよ、どういうことだ?
いい加減なことばっか教えてんじゃねぇよ、死ねよ

てかね、釣りも何も俺は見本通りにソース書いただけなんですよ
文句言うならそいつに言え
さぁ、引き続きサポートしろよ
>>988
じゃあヒントだけ教えてやろう。

"Sub または Functionが定義されていません"というメッセージはまあそのまんまの
意味なんだが、未定義のSubやFunctionを使った覚えがないのにこのエラーが
出るということは、単なるタイプミスの可能性が濃厚だ。

というわけで、上で宣言している配列変数あたりが疑わしい。つかそれだ。
てかOption Explicitって先頭に追加したら赤くなったぞ
いい加減なことばっか教えてんじゃねぇよ、死ねよ
てかタイプミスなんてあり得ません。
何万回も確認したけど俺は間違ってないからな
てかプログラミング講座気取りのサイトでも間違ったソース載っけてるバカが結構多いからな
このソース乗せてる奴もその一人なんだろうな
死ねよ
オラ、俺が次スレ立ててやったぞ
貴様ら、こっちへ来い↓
http://pc2.2ch.net/test/read.cgi/tech/1055153917/
ここはバカと一緒に1000まで埋めるスレとなりました
>>996
別にいいのに
てか一年かかってようやく1000かよ
とんだ過疎スレだな、死ねよ
俺が1000げっと
死ねよ
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。