Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Всё о задаче AdminP. Часть вторая   Во второй части мы завершаем рассмотрение AdminP. В ней рассмотрены запросы междоменного администрирования и способы управления функциями AdminP с помощью настроек документа сервера, команд консоли сервера, файла Notes.ini и интервалов очистки базы данных. В этой статье предполагается, что вы опытный администратор Domino и прочитали первую часть
О Notes Читать статью
 
Всё о задаче AdminP. Proxy-действия в R5 и Domino 6   Приложение к статье об административном процессе
О Notes Читать статью
 
Всё о задаче AdminP. Часть первая   Перевод классической статьи 2003-его года о задаче административного процесса (AdminP). Очень полезна для понимания работы механизма этой задачи. В первой части статьи описаны компоненты задачи AdminP, как они работают, и как их использование помогает сделать работу администратора Domino проще. Задача AdminP (сакращённо от Administration Process, Административный процесс) работает с базой административных запросов (Administration Requests, admin4.nsf)
О Notes Читать статью
 


Советы

Главная   Библиотека   Советы

Язык @-формул: Часть третья

Редакция проекта некоторое время сомневалась в целесообразности продолжения публикации материала, раздумывая над уместностью лозунга "Поколение RNext выбирает @For"
Но ряд вопросов, полученных от коллег, в том числе и непосредственно в адрес проекта Notesnet.ru, показал наличие востребованности решений некоторых задач на языке @-формул. В настоящем материале мы публикуем решения, любезно предоставленные в наше распоряжение Егором Ивановым


1. Сортировка числового списка (не длиннее 255 эл-тов в R6)
Следующее изящное решение продолжает демонстрацию возможностей обработки списков
Вместо числового списка можно сортировать список дат, но только не текст
На входе (SourceUniqueNumberList) должен быть список не менее 2-х различных значений

list := SourceUniqueNumberList;
e := @Left (@Text (list); 0);
dec := @Explode ("0 1 2 3 4 5 6 7 8 9");
index := @TextToNumber (@Subset (dec *+ dec *+ dec *+ dec; @Elements(list)));
reindex := @Length (@ReplaceSubstring (@Explode (@Implode ((e *+ (e + "":"")) + @Text (1 + @Sign (list *- list)); "")); "0":"1"; ""));
sorted_list := @TextToNumber (@Replace (@Text (index); @Text (reindex);@Text (list)));


2. Преобразование чисел в 16-ричные коды (строки) и обратно
Две приводимые ниже функции решают утилитарные задачи
Вызывает интерес математические приемы их решения

SourceNumber - целое беззнаковое 4-х байтное число, а его 16-ричный код (SourceHexCode), соответственно, восьмизначный.

dec := @Explode ("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
hex := @Explode ("0 1 2 3 4 5 6 7 8 9 A B C D E F");
base := @Power (16; 7:6:5:4:3:2:1:0);

nn := SourceNumber;
hh := @Implode (@Replace (@Text (@Modulo (nn / base; 16)); dec; hex); "");

hh := SourceHexCode;
nn := @Sum (base * @TextToNumber (@Explode (@ReplaceSubstring (@Right("00000000" + @UpperCase (hh); 8); hex; dec + " "))));


3. Аналог скриптовой Asc для однобайтовых символов (0 - 255)

n16 := @TextToNumber (@Explode ("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"));
asc := @Member (chr; @Char (16 * n16 *+ n16)) - 1;


4. Получение всех левых (можно и правых) подстрок заданной строки
Это решение позволяет построить большую толстую вьюшку, в которую можно будет делать @DbLookup по первым буквам значений, хотя недавно @DbLookup научился справляться с этим сам по себе
В основе формулы - построение единичной матрицы, которая может быть полезной при решении ряда других задач
В данном случае от матрицы отрезается правый треугольник нулей, хотя для получения результата все равно, какими значениями он заполнен

На входе - строка String
Length := 0;
NullList10 := "";
NullList := "";
Unitary := "";
SubstringList := "";

@Set ("SubstringList"; @If (
@Set ("Length"; @Length (String)) > 1;
@Do (
@Set ("NullList10"; @Explode ("........."; "."; @True));
@Set ("NullList"; @Subset (NullList10 *+ NullList10 *+ NullList10 *+ NullList10; Length));
@Set ("Unitary"; @Explode (@Implode ((NullList *+ (NullList + " " : "0")) : "" + (NullList *+ "1" : NullList); "")));
@Right (@Left (@Right (Unitary; "1") + "|" + String; 1 + Length); "|"));
String));
@Return (Substring)


5. Подсчет сумм в списках
И еще одна довольно часто встречающаяся задача, оперирующая со списками
Постановка задачи:
Есть два списка одинаковой длины. Один - список неуникальных объектов. Второй - соответствующее каждому объекту значение. Например, 2 списка: товары и их количество в разных магазинах.
Задача - посчитать общую сумму по каждому объекту. Их количество и названия заранее неизвестны.

Решение

Такое иногда обоями называют или простыней. На собаках удается в N строках выражения выполнить 2^N операций.

Поскольку максимальная длина списка ограничена, например, для чисел - 8К элементов, количество строк выражения ограничивается 13 одинаковыми строками.
На входе:
a - список неуникальных (повторяющихся) элементов
b - числовой список той же мощности что и a, собственно - значения
На выходе:
c - результат, числовой список

Собственно преобразование:
n := @Elements(@Unique(a));
d := @Explode ("0 1 2 3 4 5 6 7 8 9");
numbers := @Text (@TextToNumber (@Subset ( @Subset (d *+ d *+ d; -999); n)));
void := @Left (numbers; 0);
nulls := @Implode (void + "0"; " ");
diagonal := @Trim (@Explode (@Implode (@Left (@Subset ((void *+ void : "/") + (void *+ (void : "" : "" + "1" : "")) + (void *+ void : "" + "0"); n * n + n - 1); 1); " "); "/"));


matrix := @Replace (@Replace (@Text (a); numbers : @Text (a); diagonal); ""; nulls);
s := (b *+ @TextToNumber (@Explode (nulls))) * @TextToNumber (@Explode (matrix));
p := @Elements (b);
q := 0;


c := @If (
@Elements (s) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;

@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Elements (@Set ("s"; @Subset (@Subset (s; n * @Set ("q"; @Integer (p/2))) : 0 + @Subset (s; n * (q-p)); n * @Set ("p"; p-q)))) = n; s;
@Error);


6. @Adjust заданной даты на список дней (или лет, минут и т. д.) с получением соответствующего списка дат
В другом ужасном "обойном" примере реализована функция @Adjust для списковых аргументов
Особой изящностью решение не отличается, но порой возникает необходимость решения подобных задач
Расщепляется величина смещения на биты и выполняется @Adjust для каждого бита отдельно, причем сразу для двух случаев - когда бит равен 0 и когда - 1
Потом в текстовом формате аккуратно "вырезается" нужный вариант для каждого элемента списка.

Значения SourceDayOffsetList должны быть в пределах от -32768 до +32767
Чтобы расширить пределы, необходимо несколько раз скопировать повторяющуюся пару строк и соответственно увеличить значение depth
Для изменения года, месяца, часа и т.п. поменять позицию переменной bit в вызовах @Adjust.
Осторожно! Последняя пара строчек отличается от остальных знаком минус в @Adjust, контролируя самый старший - знаковый бит смещения

time := SourceDateTimeList;
offset := SourceDayOffsetList;

switch := "";
case0 := @Char (0);
case1 := @Char (1);
format := "D0T0Z2S2";
depth := "";
bit := "";

@Set ("bit"; 1);
@Set ("depth"; 16);
@Set ("offset"; offset + @Power (2; depth) * @Min (1; 1 - @Sign (offset)));
@If (
! offset >= 1; 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Do (@Set ("switch"; @Char (@Modulo (offset; 2))); @Set ("time"; @TextToTime (@Right (switch + @Text (time; format); case0) +
@Right (switch + @Text (@Adjust (time; 0; 0; - bit; 0; 0; 0); format); case1))); @Set ("bit"; 2 * bit); ! @Set ("offset"; offset / 2) >= 1); 0;
@Success);
ReturnTimeList := time;


Читайте на Notesnet.ru:
Язык @-формул. Первая часть >>>
Язык @-формул. Вторая часть >>>
 
  Опубликовано — 10/10/2004 |    

VladSh, 24.01.2005:
Сортировка списков: может я чего не допонял, но в R6.x это делает @Sort( list ; [ order ]; customSortExpression ). Для текстовых списков иногда глючит при вызове из Evaluate(). К примеру такой скрипт в 6.5.1. возвращает почему-то НЕотсортированый список: Set ND = ... ND.TextList = Evaluate({"10":"3":"8"}) TextList = Evaluate({@Sort(TextList)}, ND)



Добавить комментарий
Имя * :
e-mail
Комментарий * :
Код подтверждения * :


Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
Импорт DXL-описания документов в Lotus Domino. Одноимённые поля
16.04.2015 16:49:58
 
© LOGOSPHERE.RU