[[20250616102016]] 『データの変更ができません。』(友香) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) |

| 全文検索 | 過去ログ ]

 

『データの変更ができません。』(友香)

どこがおかしいのでしょうか?
下記のプログラムにおいて
dic("A")(0)が1ではなく0のままです。

    Dim dic As Dictionary: Set dic = New Dictionary
    Dim ary As ArrayList: Set ary = New ArrayList

    Call dic.Add("A", Array(0, ary))
    dic("A")(0) = dic("A")(0) + 1
    Debug.Print dic("A")(0)

< 使用 Excel:Excel2019、使用 OS:Windows11 >


一度作業用変数に取り出して 作業用を変更して、書き戻してあげると
出来るかも。。。^^;

m(__)m
(隠居Z) 2025/06/16(月) 10:56:48


 dictionaryのitemを配列にした場合、その要素がObject以外であれば一旦配列を変数にして更新してから再登録
 例
    Call dic.Add("A", Array(0, ary))
    Dim w
    w = dic("A")
    w(0) = w(0) + 1
    dic("A") = w
    Debug.Print dic("A")(0)
    dic("A")(1).Add "X"
    Debug.Print dic("A")(1).Count

 注意点
 aryには"X"が既に登録されています
 新たにBを下記のように登録した場合、aryは"A"で登録されたものを参照することになります。
 dic("B") = Array(0, ary)
(jindon) 2025/06/16(月) 11:18:19

 お二人から、既に適切なコメントがありました。

 蛇足ですが、追加のコメントをします。

 普通の要素1個のArrayでも同様の結果になります。
 つまり、itmの一部を変更しようとすると所期する結果は得られません。

 Sub test()      '
     Dim dic   As Object
     Dim v

     Set dic = CreateObject("Scripting.Dictionary")
     dic.Add "A", Array(0)

     Debug.Print VarPtr(dic("A")(0))   ' dic("A")(0)のポインター値・・・・(1)
     v = dic("A")(0) + 1

     dic("A")(0) = v                   'こうした書き方は不可。部分を修正することが出来ない。
     Debug.Print VarPtr(dic("A")(0))   '(1)とは異なるPtrを指している
                                       'そこに何が書き込まれたかは保証されない
     Debug.Print dic("A")(0)           '1 となるのを期待するが、実際は0となってしまう。 
 End Sub

 これを解決しようとするなら、その都度 Itemにするものを定義して、
 改めてItem に設定し直す必要があります。
 上記で言えば、
    dic("A") = Array(v)
 のようにすれば所期する結果(1)が得られます。

 ■なお、jindonさんがいみじくもご指摘されているように、Itemとして例えばdictionaryのような自身が知っているobjectであれば、
 直接的に、変更することができます。

 Sub test2() '辞書のitemがdictionaryであれば事象は発生しない
     Dim dic   As Object
     Dim dic2  As Object
     Set dic = CreateObject("Scripting.Dictionary")
     Set dic2 = CreateObject("Scripting.Dictionary")

     dic2(0) = 1
     Set dic("A") = dic2
     Debug.Print VarPtr(dic("A")(0))

     dic("A")(0) = dic("A")(0) + 1
     Debug.Print dic("A")(0)           'countupされた結果がでます。
     Debug.Print VarPtr(dic("A")(0))   'ポインターは変わりません。
 End Sub

 参考までに提示しておきます。
(xyz) 2025/06/17(火) 20:45:08

値として扱っているか参照として扱っているかということですよね。
なんとなくはわかりました。
完全に理解したとは言えませんが、
こういう場合はだめだというのはわかりました。

いろいろ試しているなかで、以下のようにするとうまくいきました。
皆さんがいうように、いったん変数を作るというやり方とは違うのですが、
これはこれでいいのでしょうか?

dic("A") = Array(dic("A")(0) + 1, dic("A")(1))

(友香) 2025/06/19(木) 08:05:27


 > 皆さんがいうように、いったん変数を作るというやり方とは違うのですが、
 > これはこれでいいのでしょうか?
 良いと思います。
 明示的に変数を設定していないだけで、itemの一部ではなく全体を作成して、
 それを key("A")のitemにセットしているわけですから、やっていることは同じです。
(xyz) 2025/06/19(木) 09:17:04

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.