如何使用 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();
}
我写了一个 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();
}