使用vba

时间:2015-09-24 12:02:55

标签: excel vba excel-vba dictionary key

我在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

我看到的是:

  1. 我之前搜索的密钥存在于字典中:表单上的目视检查
  2. 我之前搜索的密钥确实存在于字典中:"This key is the same as the acceskey"显示一次
  3. for each循环访问字典中的项目是有效的,因为C1和Fs在工作表上正确显示
  4. 然后我想也许是因为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循环中工作而不是在独立调用中。我错过了什么?这段代码与我编写的代码非常相似但不完全相同(为了让您更好地理解)。如果您认为真正的代码可以提供帮助,请告诉我。 谢谢你的帮助。

1 个答案:

答案 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应该为ObjPtrkey1返回相同的值,因为这是同一个对象,它只是分配给两个不同的变量。

现在,让我们回到字典。

字典搜索key2类型键的方式是指针。

因此,如果要在字典中找到一个以对象作为键添加的条目,则需要使用完全相同的对象(而不是具有相同属性的对象)。

示例:

Object