Классика
Как вывести поля разных записей в одной строке портала

Развитие темы "Выкладываем записи плиткой" - для iPhone и iPad.

Ранее мы показали, как расположить на экране записи "плиткой", например, в виде витрины картинок 3х3. При этом мы использовали три рядом стоящих портала и кнопки-скрипты, синхронно пролистывающие содержимое порталов порциями по 9 записей (по три записи в каждом портале).

Это хорошо работает с использованием мышки на экране десктопа. Но на телефонах и планшетах нам, конечно же, хотелось бы пролистывать записи пальцами. Для этого мы должны, во-первых, "впихнуть" все записи в один портал и, во-вторых, показывать в одной строке портала поля-картинки (в данном примере - две) из разных последовательных записей, в порядке слева-направо.

                    

Кроме того, мы должны позаботиться о том, чтобы последовательность записей всегда соответствовала нами в данный момент заданному порядку сортировки, независимо от того, в каком порядке мы вводили, создавали или удаляли записи.

Как в текущей записи показать поле из следующей записи?          

Допустим, что у нас есть таблицы Группы (товаров) и Товары.
В таблице Товары есть поле-картинка Image (тип Container) и на экране мы хотим разместить портал с прокручиваемым списком из таких картинок, расположенных парами на строке в порядке слева-направо и сверху вниз. Так же мы хотим, чтобы картинки следовали в заданном порядке в соответствии с сортировкой по тому или иному полю (например, №пп, а может быть и по Наименованию). 

Первое, что напрашивается, и самое простое - использовать функцию GetNthRecord ( fieldName ; recordNumber ), то есть создать поле

Next_Image = GetNthRecord ( Товары::Image; Get(RecordNumber) + 1)

и расположить его рядом с полем Image. После этого мы, как-то спрятав четные строчки портала, вроде бы, должны получить картинку такого вида (Рис. 1):

 Рис. 1

Но вот в этом "КАК-ТО СПРЯТАТЬ ЧЕТНЫЕ" и есть главная проблема:

1. Часто для произвольной сортировки записей мы используем числовое поле №пп. Если заводить его аккуратно, без "дырок" и повторений, то выделить четные записи было бы совсем не сложно - просто попрятать все строчки, в которых №пп = 2, 4, 6 и т.д.
Но при большом количестве записей, при возможных их удалениях, скрытиях и перемещениях поддерживать правильную нумерацию -   это довольно кропотливая и противная работа. Для обычной сортировки нам зачастую не страшны ни "дырки", ни повторения в нумерации, ни даже ее частичное отсутствие, и каждый раз перенумеровывать записи (или заставлять это делать пользователя) ну совсем не хочется.

2. Если вы сортируете записи в портале по алфавиту, например, людей по именам, то признак четности в явном виде вообще отсутствует.

3. Ничего хорошего не даст и вычисление номера записи с использованием функции Get(RecordNumber). Признаком четности (и "лишнести") может послужить нулевой остаток от деления номера записи на два:

ФлагЛишнейЗаписи = If ( Mod(Get(RecordNumber); 2) = 0; 1 ; 0)

Но, как только мы "попросим" портал спрятать четные записи, применив к порталу фильтр 

ФлагЛишнейЗаписи ≠ 1

так тут же все нечетные записи, кроме первой, одна за другой превратятся в четные и будут благополучно спрятаны.

Поскольку функция GetNthRecord также опирается на "плавающую" функцию Get(RecordNumber), то ее применение для решения нашей задачи в общем виде неприемлемо. Отсюда мы приходим к неизбежному - будем формировать признак четности сами.

Радикальное решение - принудительная нумерация "по факту"

Итак, предположим, что пользователь сам задал последовательность записей в портале - с сортировкой по любым полям или без сортировки, с группировкой или без, с фильтрами или без фильтров, с признаками "показывать/не показывать" и т.п.
Наша задача - вывести эти записи в портале так, чтобы в каждой строке портала были видны попарно поля из соседних записей (1-2, 2-3, 3-4, 4-5 и т.д.) и спрятать лишние четные записи. При этом мы не собираемся навязывать пользователю никаких правил "правильной" нумерации и ограничивать его в возможностях произвольно добавлять, удалять, пересортировывать и прятать (отфильтровывать) записи так, как он хочет.

Решение - в принудительной сквозной перенумерации текущей выборки по факту любого значимого изменения.  

1. Вводим в таблице Товары поле №ппСквозной (тип Number), недоступное пользователю для редактирования вручную.

2. Создаем скрипт, который после каждого значимого события - редактирования поля, изменения №пп или признака показывать/не показывать, добавления, удаления записи будет обновлять поле №ппСквозной, а именно -  заполнять его значениями 1,2,3,...N, где N - количество записей в текущей выборке (портале).

3. Создаем вычисляемое поле №ппСквознойПлюс1 =№ппСквозной+1

4. Для отображения "соседней" картинки (поля из следующей записи) создаем связь таблицы Товары на саму себя вида:

Здесь ключевой является вторая строчка связи №ппСквознойПлюс1 = №ппСквозной. Именно она гарантирует нам, что "соседнее" поле
Next_Image = Товары Self_№ппСквознойПлюс1|№ппСквозной|::Image 
будет отображать картинку из следующей записи именно в той последовательности, которую мы сформировали в данный момент. Она же применима и для любых других полей, которые мы хотим вывести парами (Next_Наименование, Next_Описание и т.п.)
Первая строчка связи (предварительная фильтрация товаров выбранной группы) опциональна и в вашей ситуации может быть другой или не быть вообще. 

5. Теперь к порталу, в котором мы хотим вывести записи с "парными" полями, достаточно применить сортировку по полю №ппСквозной и фильтр вида Mod ( Товары Pro GL_IDГруппа|IDГруппа|::№ппСквозной; 2) ≠ 0, т.е. показывать только записи с нечетными значениями №ппСквозной.

В результате получим желаемое - см. Рис.1 выше.


Подробности - в демо-файле. Удобнее всего проверять работу скриптов на товарной группе "Цифры".


 Демо-файл RAR архив (.fmp12)




Автор: FMLogia

Тэги: портал, две записи в одной строке портала

← Вернуться к списку статей