如何使用 Javascript 迭代 DAO 字段集合

How can I iterate the DAO fields collection with Javascript

我写了一个 HTML 运行良好的应用程序。这些文件以 .hta 结尾,只能用 Internet Explorer 打开。在应用程序中,我使用名称为 属性 的对象作为数据库的键值。由于这是 windows 和 Microsoft,我决定转换为 DAO。这些年来,我用 DAO 做了很多工作,但总是使用 VB、VBA 或 .net 语法,而不是 Javascript.

使用 Javascript,如果我将记录集中的字段命名为记录集对象的属性,即带有句点,它们是可访问的,但我必须以这种方式进行硬编码,但事实并非如此动态的。我想要做的是遍历记录集对象的字段集合并获取字段名称。我无法让它工作。它一直在说 "cannot get Name from a null instance of an object".

在下面的 db_update 函数中,我传递了一个具有 属性 名称与记录集中的字段名称相匹配的对象。该例程很灵活,可以让我避免对字段名称进行硬编码。我是那样做的,但是想改成这种格式,不行。我在 Javascript 使用 DAO 的任何地方都找不到任何信息。例程中的注释显示 "IT FAILS ON THIS LINE"。 Count 属性 以正确的值存在于 Fields 集合中,因此存在一个 Fields 集合。

function setup() {
  db_engine = new ActiveXObject("DAO.DBEngine.36");
  fso = new ActiveXObject("Scripting.FileSystemObject");
.....
  if (fso.FileExists(mdb)) fso.DeleteFile(mdb);
  db_db = db_engine.CreateDatabase(mdb,";LANGID=0x0409;CP=1252;COUNTRY=0");
  var table = db_db.CreateTableDef("file"), ord=1;
  db_create_field(table,"id",4,4,ord,false,false);
  ord++;
  db_create_field(table,"path",10,255,ord,false,false);
  ord++;
  db_create_field(table,"local",3,2,ord,false,false);
  ord++;
.....
}
function db_create_field(table,name,type,length,ordinal,required,allow_zl) {
  var fld = table.CreateField(name,type,length);
  fld.Attributes = 1;
  fld.OrdinalPosition = ordinal;
  fld.ValidationRule = "";
  fld.ValidationText = "";
  fld.Required = required ? -1 : 0;
  try {
    fld.AllowZeroLength = allow_zl ? -1 : 0;
  }
  catch(e) {
  }
  table.Fields.Append(fld);
}
function db_update(wad) {
  var rst=db_db.OpenRecordset("SELECT * FROM file WHERE path='"+wad.path+"'",2);
  if (rst.EOF) {
    rst.AddNew();
    rst.id = file_id++;
    rst.path = wad.path;
  }
  else {
    rst.edit();
  }
  var count=rst.Fields.Count, name;
  for (var j=0;j<count;j++) {
    name = rst.Fields[j].Name;  // IT FAILS ON THIS LINE FOR "NAME"
    if (wad.hasOwnProperty(name)) rst.Fields[j] = wad[name];
  }
  rst.Update();
  rst.Close();
}

新解决方案

这是我的最终解决方案,运行速度更快。搜索字段放置在 wad 之外,因此不会进行不必要的更新,也不需要枚举。如果 属性 在不在记录集字段列表中的 wad 中,当然会产生错误。

function db_update(path,wad) {
  var rst=db_db.OpenRecordset("SELECT * FROM file WHERE path='"+path+"'",2);
  if (rst.EOF) {
    rst.AddNew();
    rst.id = file_id++;
    rst.path = path;
  }
  else {
    rst.edit();
  }
  var keys = object_keys(wad);
  for (var j=0;j<keys.length;j++) rst[keys[j]] = wad[keys[j]];
  rst.Update();
  rst.Close();
}
function object_keys(obj) {
  var keys = [], j = 0;
  for (keys[j++] in obj) {};
  return keys;
}

上一个回答:

是的,枚举有效。我按如下方式更改了 db_update 例程。我希望我在发布之前想到了枚举。也许这会对其他人有所帮助。

function db_update(wad) {
  var rst=db_db.OpenRecordset("SELECT * FROM file WHERE path='"+wad.path+"'",2);
  if (rst.EOF) {
    rst.AddNew();
    rst.id = file_id++;
    rst.path = wad.path;
  }
  else {
    rst.edit();
  }
  var en = new Enumerator(rst.Fields), name;
  for (;!en.atEnd();en.moveNext()) {
    name = en.item().Name;
    if (wad.hasOwnProperty(name)) en.item().Value = wad[name];
  }
  rst.Update();
  rst.Close();
}