[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『複数コントロールのオブジェクト配列変数をクラスで定義するには?』(山川海湖)
お世話になります。
例えば、定数をクラスで定義する場合、以下の様にすれば良いことは知り得ました。
Public Property Get c1Cmb() As Integer
c1Cmb = c_c1Cmb End Property
これと同様に、変数もクラスで定義させたいのですが、その変数というのが、
オブジェクトの配列変数をクラスで定義させて、ピリオドの後に入力候補として
その変数を表示させられるようにしたいと考えています。
まず、そこまでいかないのですが、例えば、以下の様にすれば
オブジェクト配列変数を作成できそうに思っています。
(デバッグのコンパイルではエラーは出ていません)
Function SetCtrlVar(isSet As Boolean)
'//isSet=True:変数set
'//isSet=False:変数解放(Set 〜 = Nothing)
Call SetObjVarCtrl(isSet, UserForm1, uf1Cmb, "ComboBox", 1, c1Cmb) End Function
Sub SetObjVarCtrl(isSet As Boolean, ByRef UF As UserForm, _
ByRef objVar As Variant, strCtrl As String, _ iStart As Integer, iEnd As Integer) Select Case isSet Case True For iCount = iStart To iEnd Step 1 Set objVar(iCount) = UF.Controls(strCtrl & iCount) Next iCount Case False For iCount = iStart To iEnd Step 1 Set objVar(iCount) = Nothing '解放 Next iCount End Select End Sub
Call objVar.SetCtrlVar(False) '変数解放(Set 〜 = Nothing)
そこで次に、クラスから変数単位で、(ピリオドの後の)入力候補にできるように設定したいのですが、
例えば、ComboBoxが4個あるとして、1個ずつをPropertyのLetとGetに書けば良いのでしょうか?
或いは、配列として一気に書くことは可能でしょうか?
また或いは、1個ずつPropertyを作成するにしても、オブジェクト配列変数として設定できるのでしょうか?
可能なのかどうかすら、よくわかっておりませんが、
お分かりになる方がいらっしゃいましたら、ご教授頂けましたら誠にありがたいです。
お手数で誠に恐縮ですが、どうぞよろしくお願いいたします。
< 使用 Excel:Microsoft365、使用 OS:Windows10 >
Public Property Get c1Cmb() As Integer
c1Cmb = c_c1Cmb End Property (↑ここまで、「clsSetCtrlVar」というクラスに記載↑)
Function SetCtrlVar(isSet As Boolean)
'//isSet=True:変数set
'//isSet=False:変数解放(Set 〜 = Nothing)
Call SetObjVarCtrl(isSet, UserForm1, uf1Cmb, "ComboBox", 1, c1Cmb) End Function
Sub SetObjVarCtrl(isSet As Boolean, ByRef UF As UserForm, _
ByRef objVar As Variant, strCtrl As String, _ iStart As Integer, iEnd As Integer) Select Case isSet Case True For iCount = iStart To iEnd Step 1 Set objVar(iCount) = UF.Controls(strCtrl & iCount) Next iCount Case False For iCount = iStart To iEnd Step 1 Set objVar(iCount) = Nothing '解放 Next iCount End Select End Sub (↑ここまで、「clsSetCtrlVar」というクラスに記載↑)
Call objVar.SetCtrlVar(False) '変数解放(Set 〜 = Nothing)
(↑ここまで、標準モジュールに記載↑)
(山川海湖) 2023/05/03(水) 08:35:30
頭から最後まで読み込めば、
イベント処理を含めて、
コントロール配列を構築できます。
楽したいならば、
「汎用クラス/clsBpca」を使い、
「§11 サンプルコード」を参考にすれば、
色々と出来ます。
〉 As New clsCtrlObjVar
変数宣言時に New はしない方が良いですね。
Set objVar = Nothing
としても変数のメモリが解放されません。
新たに初期化された objVar が再作成されるだけです。
変数宣言後に New で初期化します。
Public objVar As clsCtrlObjVar
Set objVar = New clsCtrlObjVar
(AddinBox_角田) 2023/05/03(水) 09:28:43
― 訂正 ―
とすると、変数のメモリが解放されると同時に
新たに初期化された objVar が再作成されるだけです。
(AddinBox_角田) 2023/05/03(水) 10:15:52
>(↓ここから、「clsSetCtrlVar」というクラスに記載↓) >Dim uf1Cmb(1 To c_c1Cmb) As ComboBox
(↓ここから、「clsCtrlObjVar」というクラスに記載↓) ですよね? ~~~~~~~~~~~~~~
>例えば、以下の様にすれば >オブジェクト配列変数を作成できそうに思っています。 >(デバッグのコンパイルではエラーは出ていません)
コンパイルでエラーが出るけどなぁ。。
>Dim uf1Cmb(1 To c_c1Cmb) As ComboBox ~~~↑~~~ 変数が定義されていません。
>例えば、ComboBoxが4個あるとして、1個ずつをPropertyのLetとGetに書けば良いのでしょうか? >或いは、配列として一気に書くことは可能でしょうか?
言っている事がよく分からないですが、配列なんですから、 通常はIndexだけ変えて処理するんじゃないですか? (つまり1個のみ。じゃなければ配列にする意味がない。)
(半平太) 2023/05/03(水) 12:28:23
まずは、
AddinBox_角田さん、
変数宣言時に New はしない方が良いのですね。
Nothingとしても変数のメモリが解放されると同時に
新たに初期化された objVar が再作成されるだけなのは、
重要な基本を知る意味でも、今回大変貴重なご教授になりました。
また、VBAでは元々VBの様な「コントロール配列」機能は無いのですね。
なお、現在、リンク先などを勉強させていただいております。
(どの辺を見れば、ピンポイント良さそうでしょうか?)
あと、新たな疑問になりますが、先ほどのクラスでの定数定義におきまして、
「Property Get c1Cmb」の中で「c1Cmb = c_c1Cmb」と書きましたが、
このような定数が複数あるとして、「Property Get」自体を関数化のようにして
引数のように、「c1Cmb」や「c_c1Cmb」を送り込んで、
PropertyのGet(やLet)自体を関数化(カプセル化)できたりしますでしょうか?
或いは、やはり、定数(や変数)のGet(やLet)は、
個数分だけ1個ずつ設定が必要となるのでしょうか?
(例えば、c1Cmb、c1Lbl、c1Btn、c2Cmb、c2Chk、c2Btn、、、
など、それぞれごとにPropertyの記述が別々に必要でしょうか?
引数で送り込んで関数化みたい一括処理で定義はできないでしょうか?)
半平太さん、
>変数が定義されていません。
紛らわしい書き方となってしまい申し訳ございませんでしたが、
一番最初の質問時に、「clsSetCtrlVar」というクラスへの記述を
2か所に分けて(それらの間に日本語の補足を挿入して)
書いてしまいましたので、上側に書いた方で定義していたつもりでした。
これでしたら、変数が定義されていないエラーは出ないですかね?
>配列なんですから、通常はIndexだけ変えて処理
なるほどです。現在、書き方を検索・確認中ではありますが、
Propertyの記述も、そのようにIndexを分ければ良いのかもしれないですね。
参考にさせていただきます。
角田さん、半平太さん、ご教授いただけまして誠にありがとうございます。
まだ、書き方などを確認中ではありますが、参考にさせていただきます。
(山川海湖) 2023/05/03(水) 15:33:31
もし、そうでしたら、引数にisSetを設定して場合分けした処理は
意味のない処理になるのでしょうか?
(山川海湖) 2023/05/03(水) 16:02:16
或いは、各プロシージャ(処理)の中で、いちいち使う時に
NewをSetさせて、その各プロシージャ(処理)の最後に解放させる
というのを繰り返すしか無いのでしょうか?
(山川海湖) 2023/05/03(水) 16:38:11
やはり、プロシージャの中で、毎回、NewとNothingのSetを繰り返すしか
無さそうみたいですね。それならば、これを関数化しておいて
isSet(True or False)の引数渡しで毎回、それぞれをSetさせれば良いのかもですが。
(山川海湖) 2023/05/03(水) 16:56:49
>上側に書いた方で定義していたつもりでした。 >これでしたら、変数が定義されていないエラーは出ないですかね?
よく分からないですが、clsCtrlObjVar に全部書いてみましたら、 コンパイルエラーは出なくなりました。
ところで、(私にとって)意味不明な個所が幾つかありますよ。
> Call SetObjVarCtrl(isSet, UserForm1, uf1Cmb, "ComboBox", 1, c1Cmb) なぜ自分で持っているc_c1Cmb を直接使わないで、わざわざc1Cmbを使うんですか? そもそも引数で渡す必要すらないんじゃないですか?
uf1Cmbの配列の型はComboBoxですよね? それを何故、こんな変数に渡すんですか? ↓ ByRef objVar As Variant
しかもその名前は標準モジュールで持っているオブジェクトと同名ですよ。私は頭がおかしくなります。 またこれも引数で渡す必要すらないんじゃないですか?(自分が保持している変数なんですから)
つまり、こんな書き方になるんじゃないですか?(絶対とは言いませんが・・)
Private Const c_c1Cmb As Integer = 4 Private uf1Cmb(1 To c_c1Cmb) As ComboBox Private iCount As Integer
'Public Property Get c1Cmb() As Integer ' c1Cmb = c_c1Cmb 'End Property
Function SetCtrlVar(isSet As Boolean) '//isSet=True:変数set '//isSet=False:変数解放(Set 〜 = Nothing) Call SetObjVarCtrl(isSet, "ComboBox", 1) End Function
Sub SetObjVarCtrl(isSet As Boolean, strCtrl As String, iStart As Integer) Select Case isSet Case True For iCount = iStart To c_c1Cmb Step 1 Set uf1Cmb(iCount) = UserForm1.Controls(strCtrl & iCount) Next iCount Case False For iCount = iStart To c_c1Cmb Step 1 Set uf1Cmb(iCount) = Nothing '解放 Next iCount End Select End Sub
(半平太) 2023/05/03(水) 17:51:24
この記述方法を目指す理由や経緯は、最初の投稿時にも書きましたが、
「変数をクラスで定義し、ピリオドの後に入力候補として表示させたい」
と考えています。その為には、クラスでPropertyを定義しておき
標準モジュールなどで呼び出すと、複製クラス名のピリオドの後に入力候補として
変数などが選択できるような構造を作ろうとしている背景があります。
実際に、先ほどの定数も、例えば、標準モジュール(のどこかのsub内)で
「Public cls As clsCtrlObjVar:Set cls = New clsCtrlObjVar」などと記述しておくと
標準モジュール側からは、「cls.」と記述するだけで、そのピリオドの後に
入力候補として、先ほどの定数の「c1Cmb」や他に記述済みの関数名やsub処理名が
ぶら下がって選択肢として表示されていますので、変数でも記述が成功すれば、
今回目指している構造にできるのではないかと考えております。
ただ、今は正直、中途半端な状態でして、実は今回の質問前から既に、
拡張性などを追及したく思い、なるべくクラス内に記述しておき、後で
標準モジュールなどで関数や変数やら呼び出して使いたいと思っていましたが、
今のclsCtrlObjVarクラスモジュール内で記述しても、外からの呼び出しで無い為か
入力候補の自動表示の恩恵を受けられていません。
ですので、まずは、定数からPropertyを作成してみたところなのですが、
その(clsCtrlObjVarクラスモジュール内の)記述をそのまま投稿してしまいましたので
例えば、定数c_c1Cmbで済むのに、わざわざ、、、のご指摘はごもっともと思います。
なお、引数のUFやc1Cmbも、拡張性も考慮したり、実際に
他のUserform2以降や、他の定数でも使えるような関数化を図りたいために
わざわざ外からの引数を受ける形にしております。説明不足ですみませんでした。
今、私がclsCtrlObjVarクラスモジュール内に記述している関数やsub処理は、
この後、標準モジュールか、別のクラスモジュールに移動させて、
他の未記述の処理も含めて、ピリオドの後に入力候補を表示させられる環境の中で
記述を進めていきたいと考えております。
(今はその為に、オブジェクト配列変数を同様に記述させたくて悩んでおります。)
また、ComboBoxの配列を引数「ByRef objVar As Variant」で渡すのも
クラスモジュールで設定したいつもりのオブジェクト配列変数を、
標準モジュールなどからクラス変数を呼び出す時に、参照渡しでこのように
記述しないとコンパイルエラーが出るのではないかと私は認識しているつもりだからです。
もしかしたら 不要 又は 誤り なのかもしれないのですが。
半平太さん、色々とご協力いただけまして誠にありがとうございます。
よろしければ引き続き、どうぞよろしくお願いいたします。
(これから調べ直しですので、まだ解決できておりませんでして、すみません。)
(山川海湖) 2023/05/03(水) 22:50:27
>「Public cls As clsCtrlObjVar:Set cls = New clsCtrlObjVar」などと記述しておくと >標準モジュール側からは、「cls.」と記述するだけで、そのピリオドの後に >入力候補として、先ほどの定数の「c1Cmb」や他に記述済みの関数名やsub処理名が >ぶら下がって選択肢として表示されていますので、変数でも記述が成功すれば、 >今回目指している構造にできるのではないかと考えております。
ちょっと理解できないのですが、 単純に変数をPublic属性で定義すればいいんじゃないですか?
但し配列変数は不可なので、PropertyプロシージャとかFunctionプロシージャを使うしかないようです。 また、返って来たオブジェクト変数(配列)は、一旦同じデータ型の配列に入れてからじゃないと イメージ通りに使えないようです。 いずれにしても、Variantに型を変えたらインテリセンスが出なくなるのは当然だと思います。
>ただ、今は正直、中途半端な状態でして、実は今回の質問前から既に、 >拡張性などを追及したく思い、なるべくクラス内に記述しておき、後で >標準モジュールなどで関数や変数やら呼び出して使いたいと思っていましたが、 >今のclsCtrlObjVarクラスモジュール内で記述しても、外からの呼び出しで無い為か >入力候補の自動表示の恩恵を受けられていません。
簡単なサンプルを提示願えませんか? どのステートメントを書く途中でインテリセンスが出て来ないのか分かる様にお願いします。
>なお、引数のUFやc1Cmbも、拡張性も考慮したり、実際に >他のUserform2以降や、他の定数でも使えるような関数化を図りたいために >わざわざ外からの引数を受ける形にしております。説明不足ですみませんでした。
了解です。
(半平太) 2023/05/04(木) 11:10:27
>簡単なサンプルを提示願えませんか?
>どのステートメントを書く途中でインテリセンスが出て来ないのか分かる様にお願いします。
恐らくですが、自分自身の(クラスや)モジュールの変数だから、
インテリセンスが出てこないのだと思われます。
私がこれまで書きました様に、標準モジュールからでも、
「Public cls As clsCtrlObjVar:Set cls = New clsCtrlObjVar」のように書けば
クラス(clsCtrlObjVar)で作成した定数や関数やsub処理が「cls.」で
選択肢に呼び出せていますので、単に、同一箇所だからだと思われます。
私が今回やりたかった事は、例えば、オブジェクト配列変数「 uf1Cmb 」などを
「 cls.uf1Cmb(i) 」のように呼び出せればと思っていましたが、
もしかしますと、これは無理なのかもしれません。
>単純に変数をPublic属性で定義すればいいんじゃないですか?
>但し配列変数は不可なので、Propertyプロシージャとか
>Functionプロシージャを使うしかないようです。
>また、返って来たオブジェクト変数(配列)は、一旦同じデータ型の配列に
>入れてからじゃないとイメージ通りに使えないようです。
>いずれにしても、Variantに型を変えたらインテリセンスが出なくなるのは
>当然だと思います。
例えば、以下のようにクラスに書いても、その下のようなエラーが出てしまいます。
Public Property Let uf1Cmb(index As Integer) As ComboBox
uf1Cmb(index) = v_uf1Cmb End Property
私が調べてみたサンプルコードでも、例えば、PropertyでItemプロパティを設定して
「(コントロール変数名).Item(Index)」みたいな書き方をしていましたが、
私がやりたいことは、「uf1Cmb(i)」のような形でコーディングを楽したいことですので、
確かに、クラス化はできたとしても、今回の私には余りありがたくないのです。
繰り返しになりますが、私がやりたかったことは、「 cls.uf1Cmb(i) 」のような記述
ですので、もしかしたら、(VBAでは?)無理なのかもしれないと思いました。
いずれは、クラス化の恩恵を感じるかもしれませんが、今回、私が作ろうとした
内容であれば、クラス化してオブジェクト配列変数が扱いにくくなるよりも、
上述のような、subやfunctionでの簡略化の方が使い勝手が良さそうに感じてしまいました。
もちろん、現時点では、コンパイルエラーが出ていないというだけですから、
実際に記述を進めていって、この記述方法で問題なく動作できるかは
現時点では未確認なのですが、少なくとも、今回の私の望みは、クラス化では
実現できないのかなと思ってしまいました。(記述がかえって面倒になりそうでして)
(山川海湖) 2023/05/06(土) 02:21:17
しかし、調べてみますと、VBAの仕様なのかもですが、
オブジェクト配列変数の場合は、そう簡単にできなさそうに思えました。
少なくとも、クラスクローン名.変数名.Item(i)のような記述では、
かえって、入力手間がかかる上に、煩雑で読みにくそうですので、
なんだか手間をかけて本末転倒なことをしているように思えました。
クラスの勉強にはなっています(まだ完ぺきではないです)が、
今回私が作成しようとしている内容においては、微妙な気がしてきました。
(山川海湖) 2023/05/06(土) 02:33:45
書き方、使い方 共に間違えてる。エラーになるのは当たり前です。
Let と Get をごちゃ混ぜにしている。
――― クラスモジュール Class1 ―――
Private クラス変数1(10) As String
Private クラス変数2 As Long
Public Property Let プロパティ1(ByVal Index As Integer, ByVal データ As String)
'※ 複数の引数を指定する場合、最後の引数がこのプロパティの属性であり、
' 対になるGetと同じ属性とする
クラス変数1(Index) = データ
End Property
Public Property Get プロパティ1(ByVal Index As Integer) As String
プロパティ1 = クラス変数1(Index)
End Property
Public Property Let プロパティ2(ByVal データ As Long)
'※ 引数が1つの場合、その引数がこのプロパティの属性であり、
' 対になるGetと同じ属性とする
クラス変数2 = データ
End Property
Public Property Get プロパティ2() As Long
プロパティ2 = クラス変数2
End Property
―――――――――
Sub xxxx()
Dim クラス As Class1
Set クラス = New Class1
クラス.プロパティ1(2) = "文字列"
クラス.プロパティ2 = 123456
MsgBox クラス.プロパティ1(2)
MsgBox クラス.プロパティ2
End Sub
インテリセンスが使いたいだけならば、構造体(Type 宣言)でも可能。
Private Type abc
aaaa As Integer
bbbb(1 To 3) As String
End Type
Sub xxx()
Dim yyy As abc
yyy.aaaa = 1
yyy.bbbb(2) = "XYZ"
MsgBox yyy.aaaa & vbCrLf & yyy.bbbb(2)
End Sub
(AddinBox_角田) 2023/05/06(土) 07:19:46
>Functionプロシージャを使うしかないようです。 >また、返って来たオブジェクト変数(配列)は、一旦同じデータ型の配列に >入れてからじゃないとイメージ通りに使えないようです。 ここが、実に不可思議なのですけど、 インテリセンスが効いているのにコンパイルエラーになるんですよ。 理由が分かる人が居たら私も教えて欲しい。
あと、既述の通り、Variantにしたらインテリセンスが効かなくなるので、 これはマズいです。またネーミングもおかしい。 ↓ ByRef objVar As Variant
なので、下のコードでは ByRef objCmb() As ComboBox としています。 インテリセンスが効かない箇所は無かったです。
’---clsCtrlObjVar クラス---------
Private Const c_c1Cmb As Integer = 4 Dim uf1Cmb(1 To c_c1Cmb) As ComboBox Dim iCount As Integer
Property Get c1Cmb() As Integer c1Cmb = c_c1Cmb End Property
Function SetCtrlVar(isSet As Boolean) '//isSet=True:変数set '//isSet=False:変数解放(Set 〜 = Nothing) Call SetObjVarCtrl(isSet, UserForm1, uf1Cmb, "ComboBox", 1, c1Cmb) End Function
Sub SetObjVarCtrl(isSet As Boolean, ByRef UF As UserForm, _ ByRef objCmb() As ComboBox, strCtrl As String, _ iStart As Integer, iEnd As Integer)
Select Case isSet Case True For iCount = iStart To iEnd Step 1 Set objCmb(iCount) = UF.Controls(strCtrl & iCount) objCmb(iCount).Value = "TEST" & iCount '識別用の仮データ Next iCount
Case False For iCount = iStart To iEnd Step 1 Set objCmb(iCount) = Nothing '解放 Next iCount End Select
End Sub
Property Get PufCbxAry() As ComboBox() PufCbxAry = uf1Cmb End Property
’---標準モジュール---------
Public objVar As clsCtrlObjVar
Sub test() Dim objVar As New clsCtrlObjVar Dim cmbAry() As ComboBox
Call objVar.SetCtrlVar(True) '変数Set
' Debug.Print objVar.PufCbxAry(1).Value 'インテリセンスは効くが、コンパイルエラー(※)になる。 ' '※引数の数が一致していません。 ' ' または不正なプロパティを指定しています。
cmbAry = objVar.PufCbxAry '已むを得ず、一旦ComboBox型の配列に入れる Debug.Print cmbAry(1).Value, cmbAry(4).Value
Call objVar.SetCtrlVar(False) '変数解放(Set 〜 = Nothing) End Sub
(半平太) 2023/05/06(土) 09:40:43
ところで、今回ご提示頂きました事例は、String型とLong型ですが、
オブジェクト配列変数でも同様にできますでしょうか?
先日、ご提示頂きましたリンク先を見ていますと、
オブジェクト配列変数自体はItemプロパティを使ったり、クラスを2重にしなければ
使いまわしができなさそうにも見受けられますが、いかがでしょうか?
今更ながら、インテリセンスはプロパティかメソッドの位置づけのようですので、
確かに、(参照型?配列変数)オブジェクト自体を取得するのは少し違うのかも
しれないですし、リンク先では、Itemプロパティに本体をSetさせているようにも
見受けられました。
凡例の方?では、VBと同じ仕様として、Itemの書き方を消せると見受けましたが、
サンプルコードを見ていても、今の私では、どの部分でそれが可能となっているのか、
よく分かりませんでした。
(山川海湖) 2023/05/06(土) 13:26:09
コンパイルエラーの内容は、オブジェクト配列変数だからでは
ないのでしょうか?私がVariantを使おうとしたのは、
オブジェクト配列変数ではコンパイルエラーになったからだったような
気がしていますが、色々やっていてよく分からなくなっております。
ご提示のコードでは、「Call objVar.SetCtrlVar(True) '変数Set」の行で
「オブジェクトは、このプロパティまたはメソッドをサポートしていません」
みたいなコンパイルエラーが出ませんか?
私の貼り付け方が良くないのかもしれませんが。
(山川海湖) 2023/05/06(土) 13:27:18
インテリセンスは取れますが、Propertyでは定数っぽく書いているだけのようで
今回の私の想定した使い方はできなさそうに思えました。
ちなみに、NewはDimと分けてSetの場所で使うべきと思っていますが、
とりあえず、簡単な動作確認のつもりで試してみただけになります。
私自身が別のサイトのテクニックを真似たつもりで、Propertyで定数も
インテリセンスを取れると思っていましたが、Dimでの定数箇所には
この書き方では対応できないのかもしれないですね。
(山川海湖) 2023/05/06(土) 13:29:11
ただ、この書き方ですと、ComboBoxにしか対応できないですね。
私がVarで書いていたときは、他のコントロールについても
関数として使うために、そうしていましたので、他のコントロールで
まとめて使用できなくなってしまいました、、、
(山川海湖) 2023/05/06(土) 13:40:16
山川海湖さんのやっている事がどんなものなのかを想像しながら 進めるのはしんどいので、申し訳ないですが私はここまでとします。 m(__)m
(半平太) 2023/05/06(土) 15:46:06
半平太さん、ご教授やご指摘、ご協力いただけましてどうもありがとうございました。
(山川海湖) 2023/05/07(日) 04:00:58
私にとりましては、インテリセンスからオブジェクト配列変数も選択できれば、
入力が楽そうに思えたのですが、その為には、プロパティかメソッドのように、
それだけの個数を準備しなければならなさそうですかね。
クラスを使えば一気に処理できるのかと私は勘違いしていたかもしれません。
恐らくですが、同じような構造体を幾つも扱う時などには、一度、設計図を作成しておき
それを複製して使えば、定義とか設定が楽なのかもしれないのかなと思います。
私がクラスを使いこなすには、もう少し時間を掛けて勉強を続ける必要がありそうです。
AddinBox_角田さん、ご教授やご指摘、ご協力いただけましてどうもありがとうございました。
(山川海湖) 2023/05/07(日) 04:04:51
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.