powered by simpleCommunicator - 2.0.27     © 2024 Programmizd 02
Map
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Вопрос к знатокам Google Sheets
3 сообщений из 3, страница 1 из 1
Вопрос к знатокам Google Sheets
    #40115215
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, как правильно работать с Sheets API ?

У меня есть скрипт, который ежедневно запускается, рассчитывает определенные значения и записывает результат в Google-таблицу (точнее должен записывать).
В Google-таблице 50 столбцов, в первом указана дата, в остальных значения для этой даты.
Скрипт подключается к таблице, находит в таблице строку с нужной датой (если не находит, то добавляет новую строку), а также вносит в таблицу соответствующие значения.

Проблема в следующем.
В переменной $row находится номер строки, в которой нужно сохранять значения.
Текущие значения этой строки я считываю так:
Код: php
1.
$rs = $sh->getValues("{$ss}!{$row}:{$row}");


Здесь $sh это ссылка на объект GoogleSheets, $ss это наименование листа. В $rs возвращается ссылка на результат (объект), в этом ссылке один из методов ($rs->values) возвращает массив массивов (массив строк, внутри которого массив ячеек).

Проблема с пустыми значениями.
A) Если в строке отсутствуют данные, то в $rs->values будет пустое значение (null).
B) Если в строке заполнены все ячейки, то в $rs->values[0] возвратится массив из 50 элементов.
C) Если в строке заполнены только первые три ячейки, то в $rs->values[0] возвратится массив из 3 элементов, остальные 47 будут отсутствовать.
D) Если в строке заполнены только первая и последняя ячейки, то в $rs->values[0] возвратится массив из 50 элементов, в все значения (кроме крайних) будут пустыми.

Но проблема с тем, чтобы записать данные в таблицу.
Если я считываю массив, изменяю его значения и записываю его обратно, то все работает:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
	if (empty($rs->values)) {
		$rs = [];
	} else {
		$rs = (array)$rs->values[0];
	}
	foreach ($data as $fld=>$val)
	{
		$col = $map[$fld];
		if (count($rs) < $col) $rs = array_merge($rs, array_fill(0, ($col - count($rs)), null));
		$rs[$col-1] = $val;
	}
	$sh->setValues($ss, "{$row}:{$row}", [$rs]);


Такой код успешно работает для вариантов B и D.
Но если я добавляю ячейки справа (например были заполнены только первые два столбца, а мне нужно добавить значение в 20 столбец), то возникает ошибка:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Uncaught Google\Service\Exception: {
  "error": {
    "code": 400,
    "message": "Invalid JSON payload received. Unknown name \"0\" at 'data.values[0]': Cannot find field.\nInvalid JSON payload received. Unknown name \"49\" at 'data.values[0]': Cannot find field.",
    "errors": [
      {
        "message": "Invalid JSON payload received. Unknown name \"0\" at 'data.values[0]': Cannot find field.\nInvalid JSON payload received. Unknown name \"49\" at 'data.values[0]': Cannot find field.",
        "reason": "invalid"
      }
    ],
    "status": "INVALID_ARGUMENT"
  }
}

Значения данных в скрипте (print_r(['data'=>$data, 'rs'=>$rs])):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
Array
(
    [data] => Array
        (
            [date] => 2021-01-01
            [notes] => test
        )

    [rs] => Array
        (
            [0] => 2021-01-01
            [1] => 
            [2] => 
            [3] => 
            [4] => 
            [5] => 
            [6] => 
            [7] => 
            [8] => 
            [9] => 
            [10] => 
            [11] => 
            [12] => 
            [13] => 
            [14] => 
            [15] => 
            [16] => 
            [17] => 
            [18] => 
            [19] => 
            [20] => 
            [21] => 
            [22] => 
            [23] => 
            [24] => 
            [25] => 
            [26] => 
            [27] => 
            [28] => 
            [29] => 
            [30] => 
            [31] => 
            [32] => 
            [33] => 
            [34] => 
            [35] => 
            [36] => 
            [37] => 
            [38] => 
            [39] => 
            [40] => 
            [41] => 
            [42] => 
            [43] => 
            [44] => 
            [45] => 
            [46] => 
            [47] => 
            [48] => 
            [49] => test
        )

)

Не могу понять, что не устраивает Google.
...
Рейтинг: 0 / 0
Вопрос к знатокам Google Sheets
    #40115217
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обертка (GoogleSheets) предельно простая:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
	/**
	 * $id
	 *   Идентификатор документа (SpreadsheetID).
	 * $token
	 *   Токен авторизации (json-файл).
	 * $options
	 *   Ассоциированный массив с параметрами:
	 */
	public function __construct($id, $token, $options=null)
	{
		global $_BASE;
		if (!isset($id, $token)) throw new \InvalidArgumentException('Required parameter ommited');
		if (is_array($token)) throw new \InvalidArgumentException('Inline token not implemented, use json-file');
		if (substr($token, -5) != '.json') $token .= '.json';
		if (strpos($token, '/') === false) $token = "{$_BASE}/cfg/" . $token;
		$client = new \Google_Client();
		if (!$client) throw new \RuntimeException("Google_Client instancing failed!");
		$client->setScopes([\Google_Service_Sheets::DRIVE, \Google_Service_Sheets::SPREADSHEETS]);
		putenv("GOOGLE_APPLICATION_CREDENTIALS={$token}");
		$client->useApplicationDefaultCredentials();
		$service = new \Google_Service_Sheets($client);
		if (!$service) throw new \RuntimeException("Google_Service_Sheets instancing failed!");
		$sheet = $service->spreadsheets->get($id);
		if (!$sheet) throw new \RuntimeException("Google_Service_Sheets_Spreadsheet instancing failed!");
		$this->store = [];
		$this->store['client'] = $client;
		$this->store['service'] = $service;
		$this->store['document'] = $id;
		$this->store['sheet'] = $sheet;
	}
...
	/***
	 * Получить данные с листа
	 */
	public function getValues($sheet, $range=null, $options=[])
	{
		$svc = $this->store['service'];
		$id = $this->store['document'];
		if (isset($options))
		{
			if (!is_array($options)) $options = ['valueRenderOption'=>$options];
			$options['dateTimeRenderOption'] = 'FORMATTED_STRING';
		}
		$res = $svc->spreadsheets_values->get($id, $sheet . (isset($range) ? '!'.$range : ''), $options);
		sleep(1);
		return $res;
	}

	/***
	 * Изменить данные на листе
	 */
	public function setValues($sheet, $range, $data)
	{
		$svc = $this->store['service'];
		$id = $this->store['document'];
		$data = new \Google_Service_Sheets_ValueRange(['values'=>$data]);
		$options = ['valueInputOption'=>'USER_ENTERED'];
		$res = $svc->spreadsheets_values->update($id, $sheet . (isset($range) ? '!'.$range : ''), $data, $options);
		sleep(1);
		return $res;
	}
...
Рейтинг: 0 / 0
Вопрос к знатокам Google Sheets
    #40115218
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм...

Сделал так: if (count($rs) < $col) $rs = array_merge($rs, array_fill(0, ($col - count($rs)), ''));
Теперь ошибок нет.
То есть API чем-то не нравится null.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Вопрос к знатокам Google Sheets
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]