【发布时间】:2021-11-24 21:09:11
【问题描述】:
我有a project that I've been working on for a bit。我在这里得到了一些很好的帮助,我想我差不多完成了,只需要一点帮助才能让它工作。
脚本查看 Google 表格并获取在 A 列中输入的地名,并使用 Google Places API 查找有关它的请求信息(地址、电话号码等)
我需要的最后一点帮助将能够实现单元格输入组件。最后一个帮助我的用户说
function writeToSheet(){
var ss = SpreadsheetApp.getActiveSheet();
var data = COMBINED2("Food");
var placeCid = data[4];
var findText = ss.createTextFinder(placeCid).findAll();
if(findText.length == 0){
ss.getRange(ss.getLastRow()+1,1,1, data.length).setValues([data])
}
}
将能够使用 TextFinder 检查工作表中是否存在位置 url。如果 TextFinder 的结果为 0,它将调用COMBINED2() 来获取地点信息并用writeToSheet() 填充Sheet
他们注意到
您可以在 COMBINED2 中使用单元格输入,方法是使用 ss.getRange(range).getValue()
没有编码背景,我已经能够自己将大部分内容拼接在一起,但我可以使用一些帮助来将这种功能添加到我的代码中。任何帮助或指导都会很棒。
这是完整的代码:
// This location basis is used to narrow the search -- e.g. if you were
// building a sheet of bars in NYC, you would want to set it to coordinates
// in NYC.
// You can get this from the url of a Google Maps search.
const LOC_BASIS_LAT_LON = "40.74516247433546, -73.98621366765816"; // e.g. "37.7644856,-122.4472203"
function COMBINED2(text) {
var API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
var baseUrl = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json';
var queryUrl = baseUrl + '?input=' + text + '&inputtype=textquery&key=' + API_KEY + "&locationbias=point:" + LOC_BASIS_LAT_LON;
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var placeId = JSON.parse(json);
var ID = placeId.candidates[0].place_id;
var fields = 'name,formatted_address,formatted_phone_number,website,url,types,opening_hours';
var baseUrl2 = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=';
var queryUrl2 = baseUrl2 + ID + '&fields=' + fields + '&key='+ API_KEY + "&locationbias=point:" + LOC_BASIS_LAT_LON;
if (ID == '') {
return 'Give me a Google Places URL...';
}
var response2 = UrlFetchApp.fetch(queryUrl2);
var json2 = response2.getContentText();
var place = JSON.parse(json2).result;
var weekdays = '';
place.opening_hours.weekday_text.forEach((weekdayText) => {
weekdays += ( weekdayText + '\r\n' );
} );
var data = [
place.name,
place.formatted_address,
place.formatted_phone_number,
place.website,
place.url,
weekdays.trim()
];
return data;
}
function getColumnLastRow(range){
var ss = SpreadsheetApp.getActiveSheet();
var inputs = ss.getRange(range).getValues();
return inputs.filter(String).length;
}
function writeToSheet(){
var ss = SpreadsheetApp.getActiveSheet();
var data = COMBINED2("Food");
var placeCid = data[4];
var findText = ss.createTextFinder(placeCid).findAll();
if(findText.length == 0){
ss.getRange(ss.getLastRow()+1,1,1, data.length).setValues([data])
}
}
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu("Custom Menu")
.addItem("Get place info","writeToSheet")
.addToUi();
}
更新
这是一个共享工作表的链接,以防有人想和我一起工作。
这是我可能没有正确表达的内容。
我希望能够在 A 列中输入地名
然后,我希望能够使用自定义菜单功能运行该功能。如果 TextFinder 没有找到给定地点的地点 URL,它将查找数据并将其写入工作表。
我想以此限制 API 调用的数量,并确保将数据写入工作表,这样就不需要在每次重新打开工作表时拉取数据。
成品
非常感谢 Lamblichus 与我一起坚持这一点。我希望有一天这对其他人有所帮助。
这是完成的代码:
// This location basis is used to narrow the search -- e.g. if you were
// building a sheet of bars in NYC, you would want to set it to coordinates
// in NYC.
// You can get this from the url of a Google Maps search.
const LOC_BASIS_LAT_LON = "ENTER_GPS_COORDINATES_HERE"; // e.g. "37.7644856,-122.4472203"
function COMBINED2(text) {
var API_KEY = 'ENTER_API_KEY_HERE';
var baseUrl = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json';
var queryUrl = baseUrl + '?input=' + text + '&inputtype=textquery&key=' + API_KEY + "&locationbias=point:" + LOC_BASIS_LAT_LON;
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var placeId = JSON.parse(json);
var ID = placeId.candidates[0].place_id;
var fields = 'name,formatted_address,formatted_phone_number,website,url,types,opening_hours';
var baseUrl2 = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=';
var queryUrl2 = baseUrl2 + ID + '&fields=' + fields + '&key='+ API_KEY + "&locationbias=point:" + LOC_BASIS_LAT_LON;
if (ID == '') {
return 'Give me a Google Places URL...';
}
var response2 = UrlFetchApp.fetch(queryUrl2);
var json2 = response2.getContentText();
var place = JSON.parse(json2).result;
var weekdays = '';
if (place.opening_hours && place.opening_hours.weekday_text) {
place.opening_hours.weekday_text.forEach((weekdayText) => {
weekdays += ( weekdayText + '\r\n' );
} );
}
var data = [
place.name,
place.formatted_address,
place.formatted_phone_number,
place.website,
place.url,
weekdays.trim()
];
return data;
}
function writeToSheet() {
const sheet = SpreadsheetApp.getActiveSheet();
const FIRST_ROW = 2;
const sourceData = sheet.getRange(FIRST_ROW, 1, sheet.getLastRow()-FIRST_ROW+1, 6)
.getValues().filter(row => String(row[0]));
for (let i = 0; i < sourceData.length; i++) {
const sourceRow = sourceData[i];
if (sourceRow[4] === "") {
const text = sourceRow[0];
const data = COMBINED2(text);
sheet.getRange(FIRST_ROW+i, 2, 1, data.length).setValues([data]);
}
}
}
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu("Custom Menu")
.addItem("Get place info","writeToSheet")
.addToUi();
}
【问题讨论】:
-
那么您希望
COMBINED2(text)中的参数text引用某个单元格中的值吗?你知道那是哪张纸上的哪个单元格吗?也许它会是当前选定的单元格? -
是的,我希望能够在 A 列中输入一个地点的名称,并让
COMBINED2函数引用它,并使用请求的信息填充同一行中它旁边的单元格。 -
好的,A 列,但是如何定义行?它会是选定的单元格吗?根据您提供的信息,还不清楚。
-
对不起,口齿不清。请参阅上面的屏幕截图和共享工作表的链接。我希望能够在 A 列的 Google 表格中输入地点名称。然后它使用自定义菜单函数调用
COMBINED2函数来查看每个条目,如果 TextFinder 检查并发现它在地点 URL,它将运行该函数以提取该地点的数据并将其写入工作表。关键是它只有在发现没有地方 URL 来限制我的 API 调用时才运行该函数,并且它会将信息写入工作表,因此每次打开工作表时都不会查找它。
标签: javascript google-apps-script google-sheets google-places-api