Peek — функция скрипта
Функция Peek() возвращает значение поля в таблице для строки, которая уже загружена. Можно указать номер строки или таблицу. Если номер строки не указан, будет использована последняя запись, загруженная ранее.
Функция peek() наиболее часто используется для поиска релевантных границ в загруженной ранее таблице, то есть первое или последнее значение в конкретном поле. В большинстве случаев это значение сохраняется для дальнейшего использования, например в качестве условия в цикле do-while.
Синтаксис:
Peek(
field_name
[, row_no[, table_name ] ])
Возвращаемые типы данных: двойное значение
Аргументы:
Аргумент | Описание |
---|---|
field_name | Имя поля, для которого требуется возвращаемое значение.Вводимое значение необходимо задать в виде строки (например литералы ссылочного типа). |
row_no |
Необходима строка в таблице, которая указывает поле. Может быть выражением, но оно должно определяться по целому числу. 0 обозначает первую запись, 1 обозначает вторую и т. д. Отрицательные числа указывают порядок с конца таблицы. -1 обозначает последнюю прочитанную запись. Если элемент row_no не задан, используется -1. |
table_name | Метка таблицы без двоеточия на конце. Если элемент table_name не указан, принимается текущая таблица. При использовании вне оператора LOAD или относительно другой таблицы должен быть включен элемент table_name. |
Ограничения:
Функция может возвращать только значения из уже загруженных записей. Это означает, что в первой записи в таблицы вызов, в котором row_no имеет значение -1, будет возвращать NULL (0).
Пример 1.
Добавьте образец скрипта в свое приложение и запустите. Чтобы увидеть результаты, добавьте поля, перечисленные в столбце результатов, в лист приложения.
Код сотрудника | StartDate | EndDate | FirstCode | LastCode |
---|---|---|---|---|
101 |
02/11/2010 | 23/06/2012 | 101 | 106 |
102 | 01/11/2011 | 30/11/2013 | 101 | 106 |
103 | 02/01/2012 | 101 | 106 | |
104 | 02/01/2012 | 31/03/2012 | 101 | 106 |
105 | 01/04/2012 | 31/01/2013 | 101 | 106 |
106 | 02/11/2013 | 101 | 106 |
FirstCode = 101, поскольку Peek('EmployeeCode',0, 'EmployeeDates') возвращает первое значение элемента EmployeeCode в таблице EmployeeDates.
LastCode = 106, поскольку Peek('EmployeeCode',-1, 'EmployeeDates') возвращает последнее значение EmployeeCode в таблице EmployeeDates.
Замена значения аргумента row_no возвращает значения других строк в таблице следующим образом:
Peek('EmployeeCode',2, 'EmployeeDates') возвращает третье значение, 103, в таблице в качестве FirstCode:
Тем не менее, обратите внимание, что без указания таблицы в качестве третьего аргумента table_name функция ссылается на текущую (в данном случае внутреннюю) таблицу.
Пример 2.
Если требуется доступ к данным в более низких строчках таблицы, необходимо выполнить два действия: во-первых, загрузить всю таблицу во временную таблицу, а затем выполнить повторную сортировку с помощью Peek().
Добавьте образец скрипта в свое приложение и запустите. Чтобы увидеть результаты, добавьте поля, перечисленные в столбце результатов, в лист приложения.
Create a table in a sheet in your app with ID, List, and Value as the dimensions.
ID | Список | Значение |
---|---|---|
1 | 3,4 | 4 |
1 | 3,4,6 | 6 |
1 | 3 | 3 |
2 | 1,11 | 11 |
2 | 1 | 1 |
3 | 7,8 | 8 |
3 | 7 | 7 |
5 | 2,78 | 78 |
5 | 2,78,13 | 13 |
5 | 2 | 2 |
Оператор IF() строится на основе временной таблицы T1.
Peek('ID') ссылается на поле ID в предыдущей строке в текущей таблице T2.
Peek('List') ссылается на поле List в предыдущей строке в таблице T2, которая строится в настоящее время как оценивающееся выражение.
Оператор оценивается следующим образом:
если текущее значение элемента ID такое же, как предыдущее значение элемента ID, то значение элемента Peek('List') записывается как объединенное с текущим значением элемента Value. В противном случае записывается только текущее значение элемента Value.
Если функция Peek('List') уже содержит объединенный результат, новый результат элемента Peek('List') будет объединен с ним.
Пример 3
Добавьте образец скрипта в свое приложение и запустите. Чтобы увидеть результаты, добавьте поля, перечисленные в столбце результатов, в лист приложения.
Amount | AmountMonthBefore | Месяц |
---|---|---|
1 | 4 | 2022-06 |
2 | - | 2022-01 |
3 | 2 | 2022-02 |
4 | 9 | 2022-05 |
7 | 3 | 2022-03 |
9 | 7 | 2022-04 |
Поле AmountMonthBefore не будет содержать сумму за предыдущий месяц.
Здесь параметры row_no и table_name отброшены, поэтому используются значения по умолчанию. В этом примере следующие три вызова функции являются эквивалентными:
- Peek(Amount)
- Peek(Amount,-1)
- Peek(Amount,-1,'Amounts')
Значение -1 для параметра row_no указывает, что будет использоваться значение из предыдущей строки. В результате замены этого значения можно извлечь значения других строк таблицы:
Peek(Amount,2) возвращает третье значение в таблице: 7.
Пример 4
Данные необходимо правильно сортировать для получения правильных результатов, но, к сожалению, это не всегда выполняется. Функцию Peek() нельзя использовать для указания ссылки на данные, которые еще не загружены. Такие проблемы можно предотвратить, используя временные таблицы и выполняя несколько обходов данных.
Добавьте образец скрипта в свое приложение и запустите. Чтобы увидеть результаты, добавьте поля, перечисленные в столбце результатов, в лист приложения.
tmp1Amounts: Load * Inline [Month,Product,Amount 2022-01,B,3 2022-01,A,8 2022-02,B,4 2022-02,A,6 2022-03,B,1 2022-03,A,6 2022-04,A,5 2022-04,B,5 2022-05,B,6 2022-05,A,7 2022-06,A,4 2022-06,B,8]; tmp2Amounts: Load *, If(Product=Peek(Product),Peek(Amount)) as AmountMonthBefore Resident tmp1Amounts Order By Product, Month Asc; Drop Table tmp1Amounts; Amounts: Load *, If(Product=Peek(Product),Peek(Amount)) as AmountMonthAfter Resident tmp2Amounts Order By Product, Month Desc; Drop Table tmp2Amounts;
Объяснение
Первоначальная таблица сортируется по месяцу, таким образом функция peek() во многих случаях будет возвращать сумму для неправильного продукта. Таким образом, данную таблицу потребуется сортировать повторно. Это осуществляется путем выполнения второго обхода данных, в рамках которого создается новая таблица tmp2Amounts. Обратите внимание на предложение Order by. Оно упорядочивает записи сначала по продукту, затем по месяцу в восходящем порядке.
Необходимо использовать функцию If(), так как AmountMonthBefore следует рассчитывать, только если предыдущая строка содержит данные для того же продукта, но за предыдущий месяц. Это условие можно проверить путем сравнения продукта в текущей строке с продуктом в предыдущей строке.
Когда создается вторая таблица, первая таблица tmp1Amounts отбрасывается с использованием оператора Drop Table.
В заключение, выполняется третий проход по данным, но теперь с сортировкой месяцев в обратном порядке. Таким образом также можно рассчитать AmountMonthAfter.
Результат
Месяц | Продукт | Amount | AmountMonthBefore | AmountMonthAfter |
---|---|---|---|---|
2022-01 | A | 8 | - | 6 |
2022-02 | B | 3 | - | 4 |
2022-03 | A | 6 | 8 | 6 |
2022-04 | B | 4 | 3 | 1 |
2022-05 | A | 6 | 6 | 5 |
2022-06 | B | 1 | 4 | 5 |
2022-01 | A | 5 | 6 | 7 |
2022-02 | B | 5 | 1 | 6 |
2022-03 | A | 7 | 5 | 4 |
2022-04 | B | 6 | 5 | 8 |
2022-05 | A | 4 | 7 | - |
2022-06 | B | 8 | 6 | - |
Пример 5
Добавьте образец скрипта в свое приложение и запустите. Чтобы увидеть результаты, добавьте поля, перечисленные в столбце результатов, в лист приложения.
Результат
Квартал | SumVal | AccSumVal |
---|---|---|
2003q1 | 65000 | 65000 |
2003q2 | 132450 | 197450 |
2003q3 | 131840 | 329290 |
2003q4 | 9000 | 338290 |
2004q1 | 5250 | 343540 |
2004q2 | 24240 | 367780 |
2004q3 | 88150 | 455930 |
2004q4 | 220650 | 676580 |
Объяснение
Оператор загрузки Load *, rangesum(SumVal,peek('AccSumVal')) as AccSumVal включает рекурсивный вызов, где предыдущие значения добавляются к текущему значению. Эта операция служит для расчета аккумуляции значений в скрипте.