我正在开发一个Android应用程序,它使用谷歌电子表格作为数据库。应用程序应该使用Sheets API v4获取、附加和更新电子表格中的值。前两个函数工作正常,但我很难更新特定行。我需要找到在第一列(“批次ID”)中有特定值的行,并更新此行中的所有单元格。
现在我得到的行被修改为这样:
ValueRange response = this.mySheetsService.spreadsheets().
values().get(spreadsheetId, range).execute();
List<List<Object>> values = response.getValues();
String rangeToUpdate;
Log.i(TAG, "all values in range: " + values.toString());
int i = 0;
if (values != null) {
for (List row : values) {
i += 1;
if (row.get(0).equals(selectedBatchID)) {
Log.i(TAG, "IT'S A MATCH! i= " + i);
rangeToUpdate = "A" + (i + 1) + ":E" + (i + 1); //row to be updated
}
}
}
/*once I have the row that needs to be updated, I construct my new ValueRange requestbody and
*execute a values().update(spreadsheetId, rangeToUpdate , requestbody) request.
*/
这实际上运行良好,但我认为这是一个丑陋的解决方案,我相信有一个更好的解决方案。
我已经阅读了工作表API留档,我熟悉了诸如batchUpdateByDataFilter、DataFilterValueRange或DeveloperMetadata等概念,我觉得我应该使用这些功能来实现我想要实现的目标,但是我不能把它们放在一起,也找不到任何例子。
有人能告诉我或帮助我了解如何使用这些Sheets V4功能吗?
非常感谢。
在电子表格API中,我们有开发人员元数据的概念,它允许我们存储最终用户看不见的信息,以便以后检索和使用。在这种情况下,最好的方法是将批ID指定为特定行的元数据。我将添加基于Javascript SDK的代码。
const response = await sheets.spreadsheets.developerMetadata.search({
auth: jwtClient,
spreadsheetId,
requestBody: {
dataFilters: [
{
developerMetadataLookup: {
locationType: 'ROW',
metadataKey: 'batchId',
metadataValue: '$BATCH_ID'
}
}
]
}
});
if (response.matchedDeveloperMetadata) {
// There is a row with that id already present.
const { endIndex } = response.matchedDeveloperMetadata[0].developerMetadata.location.dimensionRange;
// Use endIndex to create the range to update the values range: `SheetName!A${endIndex}`,
await sheets.spreadsheets.values.update(
{
auth: jwtClient,
spreadsheetId,
range: `SheetName!A${endIndex}`,
valueInputOption: 'USER_ENTERED',
requestBody: {
majorDimension: 'ROWS',
values: [[]]
},
},
{}
);
} else {
// Append the value and create the metadata.
const appendResponse = await sheets.spreadsheets.values.append(
{
auth: jwtClient,
spreadsheetId,
range: 'SheetName!A1',
valueInputOption: 'USER_ENTERED',
requestBody: {
majorDimension: 'ROWS',
values: [[]]
},
},
{}
);
if (appendResponse.data.updates?.updatedRange) {
const updatedRange = appendResponse.data.updates?.updatedRange;
const [, range] = updatedRange.split('!');
const indexes = convertSheetNotation(range);
await sheets.spreadsheets.batchUpdate({ auth: jwtClient, spreadsheetId, requestBody: {
requests: [
{
createDeveloperMetadata: {
developerMetadata: {
location: {
dimensionRange: {
sheetId: 0,
startIndex: indexes[0],
endIndex: indexes[0] + 1,
dimension: "ROWS"
}
},
metadataKey: 'batchId',
metadataValue: '$BATCH_ID',
visibility: "DOCUMENT"
}
}
}
]
}});
}
}
我也有同样的要求。
首先:创建一个函数,从工作表中获取目标对象的索引,如:
private int getRowIndex(TheObject obj, ValueRange response) {
List<List<Object>> values = response.getValues();
int rowIndex = -1;
int i = 0;
if (values != null) {
for (List row : values) {
i += 1;
if (row.get(1).equals(obj.getBatchId())) {
System.out.println("There is a match! i= " + i);
rowIndex = i;
}
}
}
return rowIndex;
}
第二:创建更新方法,方法是将具有所需值“batch id”的目标对象和其他字段的新值传递给其余字段。
public void updateObject(Object obj) throws IOException, GeneralSecurityException {
sheetsService = getSheetsService();
ValueRange response = sheetsService.spreadsheets().
values().get(SPREADSHEET_ID, "Sheet1").execute();
int rowIndex = this.getRowIndex(obj, response);
if (rowIndex != -1) {
List<ValueRange> oList = new ArrayList<>();
oList.add(new ValueRange().setRange("B" + rowIndex).setValues(Arrays.asList(
Arrays.<Object>asList(obj.getSomeProprty()))));
oList.add(new ValueRange().setRange("C" + rowIndex).setValues(Arrays.asList(
Arrays.<Object>asList(obj.getOtherProprty()))));
//... same for others properties of obj
BatchUpdateValuesRequest body = new BatchUpdateValuesRequest().setValueInputOption("USER_ENTERED").setData(oList);
BatchUpdateValuesResponse batchResponse;
batchResponse sheetsService.spreadsheets().values().batchUpdate(SPREADSHEET_ID, body).execute();
} else {
System.out.println("the obj dont exist in the sheet!");
}
}
最后:在您的应用程序中,您必须将带标签的对象传递给更新方法:
TheObject obj = new Object();
obj.setBatchId = "some value";
如果需要,用其他值填充obj。
然后调用该方法:
objectChanger.updateObject(obj);
我有完全相同的问题,而且似乎到目前为止(2018年3月)Sheets v4 API不允许按值搜索,返回单元格地址。我在StackOverflow上找到的解决方案是使用一个公式。每次要按值查找地址时,可以在任意工作表中创建公式,然后删除公式。如果您不想每次都删除公式,您可能更喜欢在更安全的地方创建,例如隐藏的工作表。
职位
{
"requests": [
{
"addSheet": {
"properties": {
"hidden": true,
"title": "LOOKUP_SHEET"
}
}
}
]
}
把
{
"range": "LOOKUP_SHEET!A1",
"values": [
[
"=MATCH("Search value", MySheet1!A:A, 0)"
]
]
}
响应如下所示:
{
"updatedData": {
"range": "LOOKUP_SHEET!A1",
"majorDimension": "ROWS",
"values": [
[
3
]
]
}
}
默认情况下,主维度为行。MATCH()返回列A中的相对行,如果未提供行ID,则此位置实际上是绝对的。或者,您可能希望使用更可靠的调用,如=行(间接(地址(匹配(“搜索值”,a:a,0),1)))。如果工作表中有空格,请用单引号将其括起来。若要搜索数字,请确保不要将其括在引号中。
查找特定记录并更新
我对使用java从web获取java非常陌生,我遇到了一个问题。我正在解析一个网站(Flightradar24.com)中的JSON,并将JSON中的数据保存到CSV文件中。然而,JSON中的值会不时更新,所以每当我再次尝试解析JSON文件时,更新的值都不会保存。例如,如果我有此条目 我想得到更新,这将是: 然而,我唯一能做的就是一遍又一遍地获取相同的条目,而不更新值。我正在使用线程。sleep(
问题内容: 我想实现的想法是一个ID表。基本上,它具有以下结构(user_id,teacher_id),其中user_id是指我的User表中的主键,而讲者ID是指我的讲师表中的主键。 我正在尝试在Redis中实现此功能,但是如果我将键设置为用户的主要ID,则当我尝试运行查询时,例如 获得讲师ID = 5的所有记录, 因为讲师不是键,但是我不会 值 能够在O(1)时间到达。 如何形成上面提到的id
在我的Android应用程序,我想追加一行(与新的食品订单信息)到谷歌表格的顶部。从https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append留档听起来我只能追加到表的底部。但是我真的需要从顶部追加新行,我怀疑这是不可能的。 我能够使用以下代码将行追加到底部: 是否可以将该行附加到表的顶
问题内容: 我想从其字符串值(或可能的任何其他值)中查找一个枚举。我已经尝试了以下代码,但是在初始化程序中不允许使用静态代码。有没有简单的方法? 问题答案: 使用为每个枚举自动创建的方法。 对于任意值,请以: 仅当你的探查器告诉你以后再继续执行Map实施。 我知道它会遍历所有值,但是仅使用3个枚举值几乎是不值得的,实际上,除非你有很多值,否则我不会为Map烦恼,它会足够快。
我有一个用TypeScript编写的非常简单的应用程序: src/索引。输电系统 然后我的TypeScript配置: tsconfig.json 我可以使用npx tsc构建代码,然后使用节点运行它/构建/索引。js,访问时http://localhost:3000在浏览器中,我看到一条消息“你好,世界”--到目前为止一切都很好 现在使用我可以观察文件,看看它们是否发生变化,并在发生这种情况时重新