今だけ人気マンガ100円レンタル特集♪

(標準モジュール)
Option Explicit
Sub test()
Dim Class As Class1
Set Class = New Class1
Class.Obj = 1000
Set Class = Nothing
Set Class = New Class1
Range("a1").Value = Class.Obj
Set Class = Nothing
End Sub
(クラスモジュールClass1)
Option Explicit
Private a As Integer
Public Property Get Obj() As Integer
Obj = 2000
End Property
Public Property Let Obj(ByVal NewNumber As Integer)
a = NewNumber
End Property

上のマクロではやり取り1変数になってますがこれを配列に変えたいのですがどうすればいいでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (1件)

 


ふつうの配列を扱うときと同じように、
クラス用の配列変数を確保するだけです。

  標準モジュール
'--------------------------------------------------
Sub test()

 Dim i As Integer

 Dim Class(3) As Class1 '●クラスの配列変数を確保

   For i = 1 To 3
     Set Class(i) = New Class1
   Next i

   For i = 1 To 3
     Class(i).Obj = i * 1000
   Next i

   For i = 1 To 3
     Range("A1").Offset(i).Value = Class(i).Obj
   Next i

End Sub
'---------------------------------------------------

   クラス
'--------------------------------------------------
  Private a As Integer

  Public Property Get Obj() As Integer
    Obj = a
  End Property

  Public Property Let Obj(ByVal NewNumber As Integer)
    a = NewNumber
  End Property
'----------------------------------------------

お分かりでしょうが、質問者のコードでは、
Property Getで Obj = 2000 となってるので常に、2000が返ってきます。
で、そこはちょこっと変更してあります。
 
    • good
    • 0
この回答へのお礼

普通にクラスを配列にすればいいんですね
ありがとうございます。

お礼日時:2007/11/09 05:13

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QProperty Letについて

このようなステートメントがたくさんあります。
これはいったい何をしているのでしょうか?
Property Get と Property Setについても同様に分りません。
どなたか教えていただけないでしょうか。

Aベストアンサー

理解困難ですか?

些細な事でも、わからなかったら遠慮なく聞いてくださいね。

Property関係を熟知するVBプログラマは、ぼくの周りにも少ないです。
流れがわかっていても、どうやったら効果的/有効的になるかがわかってないのです。だから、そういう人はPropertyを使用しようともしません。
むやみやたらにPropertyを使用するのはお奨めしないけど、たくさんのサンプルプログラムを作成し、慣れない関数を多用し、研究する努力が必要だと思います。
Propertyを使用しなくても済む部分をPropertyを使用してみるとかするのもいいと思います。
作成した後、本当にPropertyは必要なのか、Propertyを使用することによって、プログラミング的に効果的であったかなどの検証をして学ぶと、より早く身に着くと思います。


むずかしい分野ですが、がんばってくださいね。

QEXCELの自動リンク箇所の確認と解除方法

「開いているブックには他のファイルへの自動リンクが設定されています。このブックを更新し、他のブックへの変更を反映しますか」といったメッセージが表示されますが、リンクを設定した記憶はありません。編集メニューでリンク先を確認するとすでにリンク先のエクセルファイルは削除済になっています。「編集」「検索」ですでになくなっているファイル名を全てのシートで検索しても「見つかりません」となってしまいます。質問No.1322325 05-04-10 回答者ja7awuさんのマクロでもリンク解除できませんでした。解除方法をご存知の方は教えてください。

Aベストアンサー

なかなかうまくいかないようですね・・・。

私の場合、検索でも見つからなかったので、コピーしたブックを使って、シートを一枚ずつ削除(または、全てクリア)し保存・開く、を繰り返して参照のあるシートを特定し、該当シートが見つかったら、転記された可能性がある式の部分削除を削除しながら、幽霊の存在を探して、式の入ったセル(範囲)を特定してから、元のシートの式を修正しました。

この場合、どのセルにも他のブックへのリンクは設定されていませんでしたが、エクセルの内部に変な情報が残っていたのが原因かと思います。

どうしてもだめなら、上記のように不正なセルを特定して削除するしか無いと思います。

QEXCEL VBAマクロ作成で、他のEXCELからデータを取り込みたい

メインプログラム(EXCEL VBA)より、
他のフォルダーにあるEXCELの項目の内容を取り込みたいです。
たとえば他のフォルダーのEXCELのRange("A2:A3").ValueをメインプログラムのRange("C2:C3").Valueにセットしたい時です。

・コマンドボタン押したら、どこのEXCELから取り込むかのポップアップ(?)は、表示はできてます。
・作業者が選んだパスとブックもMsgBoxで表示できてるので、もらう相手の場所も取得できてます。

・となると次はOPEN,INPUTですか?
テキストデータの取り込みですと、Inputでそのバッファを定義してるのですが、なんか違うような。。。

よろしくお願いします!

Aベストアンサー

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Cells(2, 2).Value ' 相手シートの B2 の値を自分自身の A1 に書き込む

readBook.Close False ' 相手ブックを閉じる
Set readSheet = Nothing
Set readBook = Nothing

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Ce...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

Qクラスモジュールを使わないとできないこと

エクセル、アクセスでvbaを利用しています。
現在はすべて標準モジュールに記載しているのですが
「クラスモジュールを使わないとできないこと」もあるのでしょうか?
クラスモジュールの使い方、必要性がいまいちわかりません。
まだ初心者な為複雑なコードは作っていません。
よろしくお願いします。

Aベストアンサー

こんにちは。

私は以前勉強がてらクラスモジュールを使ってドラクエのような
ゲーム(戦闘シーンのみ)を作りました。
これで他の方の回答にもあったインスタンスというのが
分かった気がしました。

クラスモジュールを使う私なりの解釈では
Excelに存在しない何かをExcelで使いたいときにクラスモジュールを
使います。
たとえば、Excelのオブジェクトに「車」というオブジェクトは
存在しません。
ExcelのプログラムでExcel上に車を存在させるには
車オブジェクトが必要になるので
それをクラスモジュールで定義します。
ここで車種や色、大きさといったプロパティを定義します。
そして進む、止まる、バックするといったメソッドを定義します。

これでオブジェクトができるので後は標準モジュールなどから
このオブジェクトを使います。
その時、オブジェクトをそのまま使うのではなく
オブジェクトのコピーのようなもの(インスタンス)を使います。
、、、と話は長くなるのですが、私はこんな形で解釈しています。

QVBA DictionaryオブジェクトのItemについての質問です。

エクセル2000です。
A列からE列までの1行から最終行不特定の表があります。
A列はすべて文字列で、B~Gは数値、E列は文字列です。
A列の文字列には重複があります。

この表を別シートにA列の重複がない表として作成したいと思います。
その際、列が重複する場合にはB~G列は合計数値、E列は文字列を結合させます。

Dictionaryオブジェクトを用い、A列データをKey、B~E列データを配列でItemとして下記のコードを書きました。
このコードで目的は達成しました。
質問はKeyが重複する場合、B~E列のデータを配列として取り込んだItemに次のB~E列のデータを加算あるいは結合する方法の簡略化です。
このコードではItem内の配列データを、さらに配列変数のmyArに代入して、要素ごとにForNextで回しましたが、配列変数にわざわざ代入しなくとも出来る方法があるかどうかが知りたいのです。
あるいはまったく別な方法でもかまいません。
ご教示いただければ幸いです。

Sub ItemsTest()
Dim myDic As Object, ns As Worksheet '変数宣言
Dim c As Range, cc As Range, i As Integer
Dim myAr
Set myDic = CreateObject("Scripting.Dictionary") 'myDicを用意
For Each c In Range(Cells(1, "A"), Cells(Rows.Count, "A").End(xlUp)) 'A列の各データについて
If Not myDic.exists(c.Value) Then 'myDicになければ
myDic.Add c.Value, Array(c.Offset(0, 1).Value, c.Offset(0, 2).Value, c.Offset(0, 3).Value, c.Offset(0, 4).Value) '追加しB~E列データを配列でItemに
Else 'myDicにあれば
myAr = myDic(c.Value) 'Itemを配列myArに
For i = LBound(myAr) To UBound(myAr)
myAr(i) = myAr(i) + c.Offset(0, i + 1).Value '配列の要素ごとに加算
Next i
myDic(c.Value) = myAr '配列myArをItemにもどす
End If
Next c '繰り返し
Set ns = Worksheets.Add(After:=ActiveSheet) 'シートを追加
ns.Range("A1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Keys) 'A列にKeyデータ転記
For Each cc In ns.Range("A1:A" & myDic.Count)
cc.Offset(0, 1).Resize(, UBound(myAr) + 1).Value = myDic.Item(cc.Value) 'B~E列にItemデータ転記
Next
End Sub

 (o。_。)oペコッ

エクセル2000です。
A列からE列までの1行から最終行不特定の表があります。
A列はすべて文字列で、B~Gは数値、E列は文字列です。
A列の文字列には重複があります。

この表を別シートにA列の重複がない表として作成したいと思います。
その際、列が重複する場合にはB~G列は合計数値、E列は文字列を結合させます。

Dictionaryオブジェクトを用い、A列データをKey、B~E列データを配列でItemとして下記のコードを書きました。
このコードで目的は達成しました。
質問はKeyが重複する場合、B~E列のデー...続きを読む

Aベストアンサー

こんにち わ
遅くなってすみません。さっそくですが
まずは説明の為の実験から話をすすめさせて下さい。

ご提示のソースコードで、
myDic の設定が終わった後の行、Set ns =~の行の直前に、
以下、4行を挿入して、
 Dim Arr(1) As Variant
 Arr(0) = myDic.Keys
 Arr(1) = myDic.Items
 Stop
実行後、Stop状態でローカルウィンドウを眺めて見ると、

[-] Arr ◇ myDic
├[-] Arr(0) ◇ myDic.Keys
│├[-] Arr(0)(0) ◇ myDic.Keys(0)
│├[-] Arr(0)(1) ◇ myDic.Keys(1)
│├[-] Arr(0)(2) ◇ myDic.Keys(2)
│├ ・
│└ ・
└[-] Arr(1) ◇ myDic.Items
 ├[-] Arr(1)(0) ◇ myDic.Items(0)
 │├[-] Arr(1)(0)(0) ◇ myDic.Items(0)(0)
 │├[-] Arr(1)(0)(1) ◇ myDic.Items(0)(1)
 │├[-] Arr(1)(0)(2) ◇ myDic.Items(0)(2)
 │├ ・
 │└ ・
 ├[+] Arr(1)(1) ◇ myDic.Items(1)
 ├[+] Arr(1)(2) ◇ myDic.Items(2)
 ├ ・
 └ ・

こんな樹形図が現れます。
myDicの中身を、ひとつのVariant変数Arrに喩えたら。という話ですが、
 Arrは一次元配列で、
 Arrの要素Arr(0)、Arr(1)は、それぞれ一次元配列、
 Arr(1)の要素Arr(1)(0 To X)は、それぞれ一次元配列、
 Arr(1)(0 To X)の要素はArr(1)(0 To X)(0 To Y)、
一次元多段階配列で階層構造がみえてきます。
ご提示のソースコードをみて、頭の中のイメージで
上のような樹形図が浮かび、窮屈な(かなり難しそうな)印象を受けました。
(In/Outどちらかが、樹形図様なら、自然なんでしょうけれど。)
Dictionaryで扱っているとそうは感じないのですが実際は結構複雑です。
配列の中身が配列っていうのを、二段階配列なんて呼びますけれど、
二次元配列より、難易度(扱い難さ)は上。という認識でいます。
『セル範囲→二次元配列→セル範囲』二次元で統一したら、
楽なんじゃないかな?と思って前稿を書いてみたのですが、
反ってわかり難い、ということのようですね。
それはそれで、とても感覚的なことだと思うので、
重ねて意見をおすつもりはありません。
ややっこしく感じない方法を選べばよいのです。
でもまぁ無駄になる話でもないつもりなので、時間のある時にでも、
考えて頂ければ、幸いです。

>ただ、1次元配列では配列インデックスは0から、
>二次元配列は1からだと思っていたところ、
>二次元でも0からに出来るんですね、
>しかも次元ごとに0と1を組み合わせるなんてことも!

0でも1でも、それ以上でも、自分で定義すればいいです。

 Option Base 1
とモジュールの宣言部に書いておけば(機会は少ないですが)、
 Dim A(5, 4)
は、A(1 To 5, 1 To 4)

 Option Base 0
(デフォルトでBase 0なので通常は省略しますが)ならば、
 Dim A(5, 4)
は、A(0 To 5, 0 To 4)

 どちらの場合でも
 Dim A(2 To 5, 3 To 4)
は、A(2 To 5, 3 To 4)

(以上は自分で定義した場合、以下はそれ以外)

 Option Base によらず、どちらの場合でも
 vA = Range("any").Value
は、1ベース

 v = Split("A B")
や、
 Lbound(myDic.keys)
は、0ベース、

ちょっとややこしいけど、とりあえず(myDic.keysは別としても)
これ位の場合分けを覚えておけば、困ることは少ないと思います。
使い慣れない関数、メソッドやプロパティから配列を変数に受ける時は、
ローカルウィンドウなど(できればヘルプ)で、確認すればよいです。

 vA = Range("any").Value、セル範囲の値(配列)の場合、
(行数や列数がひとつでも)必ず1ベースの二次元配列を返す。このことを、
少し混乱して覚えていたのではないでしょうか。
次元数でBaseが決まるのではなく、関数、メソッドやプロパティなど、
で決まります。

>また、ReDim Preserve vAP~で出力用配列を再定義したのは、
>当初の vAPが、Keyを取り込んだ1次元配列を、
>出力用に2次元に変換するためですね?
(後の補足欄のコメント)
>でもDictionaryって一次元配列ですよね?どうしてなんでしょう?

>>vAP = Application.Transpose(myDic.Keys) ' 出力用配列にKeysを渡す
結果は、vAP(1 To c, 1 To 1) で、この時点で、二次元になってます。
Application.Transpose()の機能によって二次元配列に変換されます。
(cはmyDic.Keys.Countと同値)
>>ReDim Preserve vAP(1 To c, 0 To lC) ' 出力用配列を再定義
1)vAP(every, 1)にあった値は、vAP(every, 0)に移ります。
LBound(,2)がLBound(,2)に移るって考えればいいと思います。
2)vAP(1 To c, 0 To lC)で、
出力側のセル範囲にサイズを合わせています
(0ベースですから、実際の列番号とは相対です)。
vAP(every, 0)は、Keys相当。
vAP(every, 1 To lC)は、計算の為の作業スペースであり、
最終的には求める値(出力する配列)にもなる、ということです。


>...書き換えてみましたが、同じでことすね?

結果は、全く同じです。
その場合は最初にlCを設定する時の-1を消して、全体を合わせて書けば、
文字数(演算回数)もほぼ(j - 1の部分以外)同じになります。
取得した配列vAVのインデックスを基準にするか、
シート上の列番号を基準にするか、の違いだけです。
工夫の余地はあると思います。

>縦ヨコでインデックスが異なる

>> vAP(lB, j) = vAP(lB, j) + vAV(i, j)
iは、元の(重複を含む)表の行を上から下に走る。
元の表のi行めにあるキーとなる(1列めの)文字列は
myDic.KeysのlB番め(1から数えて)にあるから、
■出力側のlB行め(キーに対応したユニークな位置)の、
■j列(元の表、出力側の表、ともに2列めが1となる相対位置)の
■【vAP(lB, j)】
 に、
◆元の(重複を含む)表のi行めの、
◆j列(元の表、出力側の表、ともに2列めが1となる相対位置)の
◆【vAV(i, j)】
 を
 加算(連結)する
うーん、、、うまく伝わるかなぁ。

前後しましたが、
>> つまりテーブル操作をDictでやるという趣旨でしょうか?
>「テーブル操作」って何でしょう?のレベルなものですから・・・。
これは答えるの難しいですね。
私自身が用語を未整理なまま使ってしまいました。すみません。
そうでなくても難しいのですけれど。
「テーブル」という表現をやめて「表」でいうと、
「ある表から、もうひとつの表を参照して、新たな表を作る。」
私が書いたものでは、
myDicは、Key文字列と対応するID(インデックス)とでひとつの「表」
(よくLOOKUP等の関数で参照先セル範囲にあるリストのよう)になっていて、
元のシートにある「表」とをすり合わせて、
新しいシートに新しい「表」を作っています。
(ここからはまた、感覚的なのですが、)私にはご提示のソースコードが、
上に書いたような意味で同じように"見える"ということです。
拡大解釈をすれば、データベースにとってのクエリに似たような処理、
ですよね。それをDictを使って処理するのは目から鱗ですね。
ってな感じのことを言わんとしたのですが、あまり深く考えないでおいて
貰えると、私も幸せになれるのですが(^^;)。

自己レス
>>文字列の連結に+演算子を使うことについては、
>>Variant変数同士ですから、ま、いいかな、と。
ダメじゃん。せいぜい、
 Variant変数同士ですし、条件が合うなら、ま、いいかな、とも思います。
あと、
>>勝手に.CurrentRegionにしてますが、
 元のセル範囲の行数を取得することなく実現することで、
 For Each で回すメリットを強調したかったもので、、、。

全体に書き足りないこと書きすぎていることが目立ってわかり難くなって
ました(反省)。いつも、すみません。

こんにち わ
遅くなってすみません。さっそくですが
まずは説明の為の実験から話をすすめさせて下さい。

ご提示のソースコードで、
myDic の設定が終わった後の行、Set ns =~の行の直前に、
以下、4行を挿入して、
 Dim Arr(1) As Variant
 Arr(0) = myDic.Keys
 Arr(1) = myDic.Items
 Stop
実行後、Stop状態でローカルウィンドウを眺めて見ると、

[-] Arr ◇ myDic
├[-] Arr(0) ◇ myDic.Keys
│├[-] Arr(0)(0) ◇ myDic.Keys(0)
│├[-] Arr(0)(1) ◇ myDic.Keys(1)
│├[-] Arr(0)(2) ◇...続きを読む


人気Q&Aランキング