我在vba中访问字典中的项目时遇到了问题。
我有以下字典:
Dim CResults as dictionary
我添加了项目:
CResults.add currentkey, result
Currentkey
是我自己从名为DCRkey
Private loadcase as long
Private csystem as String
Private node as long
和result
是名为DCR
的类中的另一个对象:
Private Fs as double
Private C1 as double
Private C2 as double
...
然后我尝试使用
访问某个项目Dim accesskey as DCRKey
accesskey.loadcase=10
accesskey.node = 2000
accesskey.csystem="Global"
Sheets("Results").cells(i,1).value= CResults(accesskey).C1
这就是我收到错误的地方:runtime error 424 object required
然后我想也许我搜索的键和项目没有导入,所以我决定在excel工作表上显示我的整个字典:
Dim testkey as variant
dim i as integer
i=1
with worksheet("Test")
For each testkey in CResults.keys
.cells(i,1)=test.node
.cells(i,2)=test.loadcase
.cells(i,3)=test.csystem
.cells(i,4)=Cresults(testkey).C1
.cells(i,5)=Cresults(testkey).Fs
if accesskey.loadcase=testkey.loadcase and accesskey.node=testkey.node and accesskey.csystem=testkey.csystem then
Msgbox "This key is the same as the accesskey"
End if
i=i+1
Next
End with
我看到的是:
"This key is the same as the acceskey"
显示一次for each
循环访问字典中的项目是有效的,因为C1和Fs在工作表上正确显示然后我想也许是因为testkey
被定义为变体而不是DCRKey
,所以我试过了:
dim a as variant
Set a = currentkey
.Cells(i,1) = CResults(a).C1
但它不起作用,我仍然得到了runtime error 424
。
我也尝试过:
CResults.exists(accesskey)
它返回false并在字典中创建一个新条目(顺便提一下,当它这样做时),使用与acceskey相同的键和一个空项。
所以我的问题是:为什么使用自定义类型键访问项目在for each
循环中工作而不是在独立调用中。我错过了什么?这段代码与我编写的代码非常相似但不完全相同(为了让您更好地理解)。如果您认为真正的代码可以提供帮助,请告诉我。
谢谢你的帮助。
答案 0 :(得分:5)
您需要记住,类的两个实例不是同一个,即使它们的所有属性都设置为相同的值。
让我们考虑以下示例:
#include <iostream>
#include <stdio.h>
using namespace std;
class FlyingMode {
protected:
float time, fuel_rate, start, end, pace, distance;
float total;
public:
FlyingMode(float a=0, float b=0, float c=0,
float d=0, float e=0, float f=0){
time = a;
fuel_rate = b;
start = c;
end = d;
pace = e;
distance = f;
total = 0;
}
virtual int calcFuel(){
return 0;
}
};
class Holding: public FlyingMode{
public:
Holding(float a=0, float b=0, float c=0,
float d=0, float e=0, float f=0):FlyingMode(a, b, c, d, e, f) { }
int calcFuel(){
total = (time * fuel_rate * 60);
return total;
}
};
class Raising: public FlyingMode{
public:
Raising(float a=0, float b=0, float c=0,
float d=0, float e=0, float f=0):FlyingMode(a, b, c, d, e, f) { }
int calcFuel (){
if(start < end && pace != 0 ){
total = (end - start)/pace * fuel_rate;
return (end - start)/pace * fuel_rate;
}else{
return 0;
}
}
};
class Landing: public FlyingMode{
public:
Landing(float a=0, float b=0, float c=0,
float d=0, float e=0, float f=0):FlyingMode(a, b, c, d, e, f) { }
int calcFuel (){
if(start > end && pace != 0 ){
total = (start - end)/pace * fuel_rate;
return (start - end)/pace * fuel_rate;
}else{
return 0;
}
}
};
class Straight: public FlyingMode{
public:
Straight(float a=0, float b=0, float c=0,
float d=0, float e=0, float f=0):FlyingMode(a, b, c, d, e, f) { }
int calcFuel (){
if(distance != 0 || pace != 0 ){
total = distance/pace * fuel_rate;
return distance/pace * fuel_rate;
}else{
return 0;
}
}
};
// Main function for the program
int main( ){
float a=0, b=0;
float c=0, d=0, e=0, f=0;
float total = 0;
char op;
Holding hold;
Raising raise;
Landing land;
Straight straight;
while(op != 'x') {
cout << "Enter the move : " << endl;
cout << "1 ---> Holding Flight" << endl;
cout << "2 ---> Raising" << endl;
cout << "3 ---> Landing " << endl;
cout << "4 ---> Straight Flight " << endl;
cout << "5 ---> Calculate fuel" << endl;
cout << "x ---> Exit " << endl;
cin>>op;
cout<<"op="<<op<<endl;
if(op == '1') {
cout << "Enter time : ";
cin >> a;
cout << "Enter fuel rate: ";
cin >> b;
}
else if(op == '2') {
cout << "Enter starting altitude: ";
cin >> c;
cout << "Enter ending altitude: ";
cin >> d;
cout << "Enter raising pace: ";
cin >> e;
cout << "Enter fuel rate: ";
cin >> f;
}
else if(op == '3') {
cout << "Enter starting altitude: ";
cin >> c;
cout << "Enter ending altitude: ";
cin >> d;
cout << "Enter landing pace: ";
cin >> e;
cout << "Enter fuel rate: ";
cin >> b;
}
else if(op == '4') {
cout << "Enter ending altitude: ";
cin >> d;
cout << "Enter starting altitude: ";
cin >> c;
cout << "Enter fuel rate: ";
cin >> b;
}
else if(op == '5') {
cout <<"Total required fuel : "<< total << " kg/second "<< endl;
}
else if(op == 'x') {
cout << "System will exit..." << endl;
return 0;
}
else {
//if(op==(1|2|3|4|5)){}
//else cout << "Wrong selection." << endl;
continue;
}
FlyingMode *mode;
hold = Holding(a, b, 0, 0, 0, 0);
raise = Raising(0, f, c, d, e, 0);
land = Landing(0, b, d, c, e, 0);
straight = Straight(0, b, c, d, 0, 0);
//store holding address
//call holding fuel
mode = &hold;
float hold_result = mode -> calcFuel();
//call raising fuel
mode = &raise;
float raise_result = mode -> calcFuel();
//call landing fuel
mode = &land;
float land_result = mode -> calcFuel();
//call straight fuel
mode = &straight;
float str_result = mode -> calcFuel();
//calculate total
/*cout << "hold_result" << hold_result;
cout << "raise_result" << raise_result;
cout << "land_result" << land_result;
cout << "str_result" << str_result;*/
total = total+hold_result + raise_result + land_result + str_result;
cout <<"Total required fuel : "<< total << " kg/second "<< endl;
}
return 0;
}
在此示例中,Sub compareSimilarObjects()
Dim key1 As DCRKey
Dim key2 As DCRKey
Set key1 = New DCRKey
With key1
.loadcase = 10
.node = 2000
.csystem = "Global"
End With
Set key2 = New DCRKey
With key1
.loadcase = 10
.node = 2000
.csystem = "Global"
End With
'Debug.Print to check pointer assigne to those variables.
Debug.Print "Key1: " & ObjPtr(key1)
Debug.Print "Key2: " & ObjPtr(key2)
End Sub
类的两个对象都将所有属性设置为相同的值。但是,它们与下面的代码在最后运行DCRKey
后看到的对象不同。
在那些Debug.Prints
中使用了VBA内置函数Debug.Print
。此函数的目的是返回指向给定对象的指针。对象的每个实例都有自己唯一的指针,因此如果下面的代码打印了两个不同的指针,则表示这些对象不相同。
现在,让我们考虑另一个例子:
ObjPtr
在这里,我们为变量Sub compareSimilarObjects()
Dim key1 As DCRKey
Dim key2 As DCRKey
Set key1 = New DCRKey
With key1
.loadcase = 10
.node = 2000
.csystem = "Global"
End With
Set key2 = key1
'Debug.Print to check pointer assigned to those variables.
Debug.Print "Key1: " & ObjPtr(key1)
Debug.Print "Key2: " & ObjPtr(key2)
'Now those pointers should be the same.
End Sub
分配了一个新的类DCRKey
实例,然后我们将相同的对象分配给变量key1
。现在key2
应该为ObjPtr
和key1
返回相同的值,因为这是同一个对象,它只是分配给两个不同的变量。
现在,让我们回到字典。
字典搜索key2
类型键的方式是指针。
因此,如果要在字典中找到一个以对象作为键添加的条目,则需要使用完全相同的对象(而不是具有相同属性的对象)。
示例:
Object