使用 office-js 删除 excel table 中的行
Deleting rows in excel table with office-js
我在我的添加中有一个 ajax 调用,它应该在其中创建或更新 excel 中的 table。如果 table 已经存在,它应该删除行并添加新结果。
在循环中删除行时,它正在删除一些行,然后出现以下错误:
Debug info: {"code":"InvalidArgument","message":"The argument is invalid or missing or has an incorrect format.","errorLocation":"TableRowCollection.getItemAt"}
我的 ajax 在我的 excel 网络加载项中的调用如下所示:
$.ajax({
//....
}).done(function (data) {
Excel.run(function (ctx) {
var odataTable = ctx.workbook.tables.getItemOrNullObject("odataTable");
//rows items are not available at this point, that is why we need to load them and sync the context
odataTable.rows.load();
return ctx.sync().then(function () {
if (odataTable.rows.items == null) {
odataTable.delete();
odataTable = ctx.workbook.tables.add('B2:G2', true);
odataTable.name = "odataTable";
} else {
console.log("Rows items:" + odataTable.rows.items.length);
odataTable.rows.items.forEach(function (item) {
console.log("Removing row item: " + item.values);
item.delete();
});
console.log("rows cleaned");
}
}).then(function () {
//add rows to the table
});
}).then(ctx.sync);
}).catch(errorHandler);
}).fail(function (status) {
showNotification('Error', 'Could not communicate with the server. ' + JSON.stringify(status));
}).always(function () {
$('#refresh-button').prop('disabled', false);
});
可迭代集合的想法是它们由不同的项目组成。一旦您以不适当的方式从这些项目中删除了某些内容,该集合就不再是一个集合。这是因为它们是作为链表实现的,其中每个单元只知道下一个单元。 https://en.wikipedia.org/wiki/Linked_list
在你的例子中,你正在删除一个 for-each 循环。第一次删除后,集合被破坏。因此,您需要另一种方法。
另一种方法:
开始使用普通的 for 循环进行循环。反转。
例如:
for i = TotalRows to 1 i--
if row(i) something then delete
这已经有人回答了,但我最近自己解决了这个问题,来这里看看是否有人发布过有关它的问题。
当您删除一行时,Excel 将对每行的行索引重新排序:即,当您删除第 1 行时,第 2 行变为第 1 行,所有其他行都会向下移动 1 个索引。因为这些删除是push到一个batch来完成的,当第二次删除执行的时候,你的第二行已经变成了第一行,所以它实际上跳过了第二行,执行了你认为是你的第三行。
如果您从最后一行开始并向后工作,则不会发生这种重新排序,也不会发生错误。
为了完整起见,上面的例子将变成:
return ctx.sync().then(function () {
if (odataTable.rows.items == null) {
odataTable.delete();
odataTable = ctx.workbook.tables.add('B2:G2', true);
odataTable.name = "odataTable";
} else {
console.log("Rows items:" + odataTable.rows.items.length);
for (let i = odataTable.rows.items.length -1; i >= 0; i--) // reverse loop
odataTable.rows.items[i].delete();
}
console.log("rows cleaned");
}
我在我的添加中有一个 ajax 调用,它应该在其中创建或更新 excel 中的 table。如果 table 已经存在,它应该删除行并添加新结果。 在循环中删除行时,它正在删除一些行,然后出现以下错误:
Debug info: {"code":"InvalidArgument","message":"The argument is invalid or missing or has an incorrect format.","errorLocation":"TableRowCollection.getItemAt"}
我的 ajax 在我的 excel 网络加载项中的调用如下所示:
$.ajax({
//....
}).done(function (data) {
Excel.run(function (ctx) {
var odataTable = ctx.workbook.tables.getItemOrNullObject("odataTable");
//rows items are not available at this point, that is why we need to load them and sync the context
odataTable.rows.load();
return ctx.sync().then(function () {
if (odataTable.rows.items == null) {
odataTable.delete();
odataTable = ctx.workbook.tables.add('B2:G2', true);
odataTable.name = "odataTable";
} else {
console.log("Rows items:" + odataTable.rows.items.length);
odataTable.rows.items.forEach(function (item) {
console.log("Removing row item: " + item.values);
item.delete();
});
console.log("rows cleaned");
}
}).then(function () {
//add rows to the table
});
}).then(ctx.sync);
}).catch(errorHandler);
}).fail(function (status) {
showNotification('Error', 'Could not communicate with the server. ' + JSON.stringify(status));
}).always(function () {
$('#refresh-button').prop('disabled', false);
});
可迭代集合的想法是它们由不同的项目组成。一旦您以不适当的方式从这些项目中删除了某些内容,该集合就不再是一个集合。这是因为它们是作为链表实现的,其中每个单元只知道下一个单元。 https://en.wikipedia.org/wiki/Linked_list
在你的例子中,你正在删除一个 for-each 循环。第一次删除后,集合被破坏。因此,您需要另一种方法。
另一种方法:
开始使用普通的 for 循环进行循环。反转。 例如:
for i = TotalRows to 1 i--
if row(i) something then delete
这已经有人回答了,但我最近自己解决了这个问题,来这里看看是否有人发布过有关它的问题。
当您删除一行时,Excel 将对每行的行索引重新排序:即,当您删除第 1 行时,第 2 行变为第 1 行,所有其他行都会向下移动 1 个索引。因为这些删除是push到一个batch来完成的,当第二次删除执行的时候,你的第二行已经变成了第一行,所以它实际上跳过了第二行,执行了你认为是你的第三行。
如果您从最后一行开始并向后工作,则不会发生这种重新排序,也不会发生错误。
为了完整起见,上面的例子将变成:
return ctx.sync().then(function () {
if (odataTable.rows.items == null) {
odataTable.delete();
odataTable = ctx.workbook.tables.add('B2:G2', true);
odataTable.name = "odataTable";
} else {
console.log("Rows items:" + odataTable.rows.items.length);
for (let i = odataTable.rows.items.length -1; i >= 0; i--) // reverse loop
odataTable.rows.items[i].delete();
}
console.log("rows cleaned");
}