Книга знаний

1С:Предприятие

Прокрутка сообщений!

Здорово, пипл! Тема сегодняшнего урока - юзабилити. Если судить по тем обработкам, которые валяются на просторах тырнета, это тема очень актуальна. Сегодня, перцы, я покажу вам как мониторить сообщения. Ни для кого не секрет, что стандартный message от всеми любимой нами фирмы "1С", если мягко говорить, немного неудобный. Рассмотрим, как хранить, сэйвить, а заодно клерасилить логи. Для пущего эффекта крутить логи мы будем на форме обработки.Автор статьи: skunk | Редакторы: Волшебник
Последняя редакция №8 от 10.01.06 | История
URL: http://kb.mista.ru/article.php?id=64

Начало


Итак, начнем с начала и продолжим до самого конца ;)). Кидаем на форму текст и лезем в его свойства. Там в строке идентификатор обзываем его lbMonitor. Делаем его нужного нам размера, а заодно ставим его в нужное нам место. Решайте сами, каким размером и куда его тыкать. Ведь дизайнеры сейчас Вы. Также кинем на форму кнопку, которую обзовем btAction. В ее капшене (надпись) напишем Действия. Под форму кинем еще один объект типа "Текст", только теперь лезем в формулу и там пишем "SetEnableAction()". Все остальное по вашему желанию и хотению. Как только с дизайнерством покончите, переключайтесь в модуль обработки. Будем баловаться.

Баловство


Начнем как обычно с попы. Если быть точнее, то с функции SetEnableAction(), мы ведь ее не зря писали. Она у нас будет рулить доступностью кнопки btAction. Если у нас в мониторе что-то есть, то она доступна, иначе – нет. Сама функция очень простая. Смотрите код, там все по-русскии:

//*******************************************
function SetEnableAction()
   if strlen(Form.lbMonitor.Caption()) = 0 then
      Form.btAction.Enable(0);
   else 
      Form.btAction.Enable(1);
   endif;
endfunction


Смотрим, что у нас в мониторе есть. Если нифига нет, то доступ к кнопке отключаем. Вкурили? Тогда курим дальше. Курить дальше будем кнопку. Если быть точнее, научим ее реагировать на различные поползновения юзверей. То есть, разрешим ей кое-что делать с информацией в мониторе. Итак, мастерим нашу процедурку:

//*******************************************
procedure btAction()
   vlAction = createobject("valuelist");
   vlAction.AddValue("clear", "К ядреной матери");
   vlAction.AddValue("show", "Заказать историю...");
   vlAction.AddValue("save", "Записать историю...");
   strCommand = "";
   if vlAction.ChooseValue(strCommand, , , , 1) > 0 then
      if strCommand = "clear" then
      elsif strCommand = "show" then
      elsif strCommand = "save" then
      endif;
   endif;
endprocedure


Что тут и за чем, объяснять думаю не надо. Надо? Ну, грубо создаем список значений, в который заталкиваем набор необходимых нам действий. И даем выбрать пользователю, нужное действие, когда он кликнет по кнопочке. Программировать сами действия будем несколько позже. Когда закодим монитор.

Монитор


Хм, так сказать начинаем делать основную вещь. Выводить на форму текст. Ясно, что текст надо будет выводить в несколько строк. Глупо же крутить монитор в одну строку. Для того, чтобы знать, сколько строк нам отображать, заведем переменную, в которой будем хранить максимальное количество строк. Еще нам потребуется ограничитель по скорости, тьфу, количеству символов в строке. Для хранения истории сообщений заведем переменную типа Текст. Все три переменных должны быть доступны любой процедуре и функции в модуле. То есть делаем их глобальными в нашем модуле.

Объявляем:
//*******************************************
var intCountStrMonitor, intCountChar;
var txtHistory;


Инициализируем:
//*******************************************
procedure OnOpen()
intCountStrMonitor = 16;
    intCountChar = 60;
    txtHistory = createobject("Text");
endprocedure


Все ограничители подбираются опытным путем. Для вывода сообщения в монитор заводим процедуру, которая по дефолту будет мессачить пустую строку.

//*******************************************
procedure InputMonitor(strMessage = "")
endprocedure


Для начала получим то, что уже вывели на «экранчик»:

strMonitor = Form.lbMonitor.Caption();


Далее начнем разбираться с переданной строкой. И первое, на что обратим внимание, будет linebreak, так как строка может быть многострочной. Как известно, стандартный linebreak состоит из двух символов chr(10) & chr(13). А вот чтобы разделить строки в нашем «мониторе», достаточно одного chr(10). К тому же наличие chr(13) вызывает некоторые неудобства при выводе нужной части «истории сообщений». Так что chr(13) посылаем в баню:

strMessage = strreplace(strMessage, chr(13), "");


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

strMessage = strCutLength(strMessage, intCountChar);
strMonitor = ?(strlen(strMonitor) = 0, "", strMonitor + chr(10)) + strMessage;


Теперь посмотрим, сколько у нас строк в strMonitor, и, если больше допустимого лимита, сделаем им кирдык:

while strcountoccur(strMonitor, chr(10)) > intCountStrMonitor do
    strMonitor = right(strMonitor, strlen(strMonitor) - find(strMonitor, chr(10)));
enddo;


Ну и все. Осталось отобразить на «экране монитора» полученный результат.

Form.lbMonitor.Caption(strMonitor);


История


Теперь займемся историей. Только не той что в учебниках, да на всяких форумах. А историй того, что мы выводили в монитор, чтобы оное можно было смотреть, удалять и куда-нибудь сохранять. Как уже говорилось выше, история будет храниться в переменой txtHistory. В историю, конечно, можно добавлять, имея метод AddLine, но при таком раскладе злополучный chr(10) принимает не совсем кошерный вид. Поэтому будем добавлять кусками:

intPos = find(strMessage, chr(10));
while intPos > 0 do
    txtHistory.AddLine(left(strMessage, intPos - 1));
    strMessage = right(strMessage, strlen(strMessage) - intPos);
    intPos = find(strMessage, chr(10));
enddo;


strCutLength()


Функция это будет рекурсивна. Для чего? Объясняю. Допустим нам передали строку длиной в 180 символов а наш ограничитель всего на 60. Да и есть еще один бэнч. В строке уже может присутствовать символ конца строки. Вот вся функция целиком:

//*******************************************
function strCutLength(strTemp = "", intLength = 255)
    Answer = strTemp;
    if strlen(Answer) > intLength then
        intLineBreak = find(Answer, chr(10));
        if intLineBreak = 0 then
            if strlen(Answer) > intLength then
                Make = "yes";
                intPos = intLength;
                while Make = "yes" do
                    chrSimb = mid(Answer, intPos, 1);
                    if find("""'()\*/-+=_&,.?!^ ", chrSimb) > 0 then
                        Make = "no";
                    else
                        intPos = intPos - 1;
                        if intPos = 0 then
                            intPos = intLength;
                            Make = "no";
                        endif;
                    endif;
                enddo;
                Answer = left(Answer, intPos) + chr(10) +
                         strCutLength(right(Answer, strlen(Answer) - intPos), intLength);
            endif;
        elsif intLineBreak > intLength then
            Answer = strCutLength(left(Answer, intLineBreak - 1), intLength) + chr(10) + 
                     strCutLength(right(Answer, strlen(Answer) - intLineBreak), intLength);
        else
            Answer = left(Answer, intLineBreak) + 
                     strCutLength(right(Answer, strlen(Answer) - intLineBreak), intLength);
        endif;
    endif;
    return Answer; 
endfunction 


Опять к «Действиям»


Возвращаемся к нашей процедуре, которая обрабатывает клик по кнопке btAction. Начнем с очистки истории. Спросим, а то вдруг юзер щелкнул случайно или уже передумал. Если дает добро, то удаляем:

if doquerybox("Вы действительно хотите очиcтить хистори?", 4) = 6 then
    txtHistory.Clear();
    Form.lbMonitor.Caption(strMonitor);
    domessagebox("Истории - писец!!!");
endif; 


Следующим пунктом у нас идет шоу. Показывать тоже просто. Вот только одна байда, show объекта text очищает содержимое переменной. Поэтому будем казать не нашу переменную, а другую, предварительно сохранив историю на винтике.

strNameFile = userdir() + "$$$.tmp";
txtHistory.Write(strNameFile);
txtFile = createobject("Text");
txtFile.Open(strNameFile);
txtFile.Show("Ну, типа и вся история");
fs.DeleteFile(strNameFile); 


Ну и последнее, научимся хранить историю.

strPath = fs.GetCurrentDirectory();
strFile = "";
if fs.SelectFile(1, strFile, strPath, "сэйвим хистории", "Файло для хистории (*.hst)|*.hst", "*.hst") > 0 then
    txtHistory.Write(strPath + strFile);
endif;


Ну, вроде все. Удачи, вам в делах наших тяжких ;))

Пример к статье: http://www.kb.mista.ru/files/64/scrolling-1.zip

Санкт-Петербург, Декабрь 2005 года.
skunk

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика