понедельник, 26 июля 2010 г.

1С 8.2: Отключить сортировку в динамическом списке

Все форумы в один голос утверждают, что нельзя отключить сортировку динамического списка, которая включается по щелчку по заголовку колонки.
И все-таки есть один трюк, который позволит отключить сортировку. Логика простая - если клик по заголовку сбивает сортировку, то просто отключите заголовки!
Конечно, это может оказаться неудобным решением, но для простых списков можно применять:

Номенклатура:
Тапки10 грн.
Сапоги83 грн.
Мокасины2000 грн.

Тут и без заголовков очевидно какая колонка что означает.

Еще можно применить трикс и сделать элемент списка, который при вашей сортировке всегда будет вверху, а в его реквизиты записать название колонок, но имейте ввиду, что это все-равно, что чесать левое ухо левой рукой через жопу. Используйте возможности платформы по назначению и будет вам счастье!

воскресенье, 25 июля 2010 г.

Обработка проверки заполнения константы. Контекст превыше всего!

Сегодня речь пойдет о "модуле менеджера значения" у объекта "константа". Зачем нужен этот модуль и как его применять? Конечно, в нем можно описать произвольную экспортную процедуру или функцию и вызывать ее из любого места вашей конфигурации, получив предварительно модуль менеджера значения вашей константы. Вызов может выглядеть, например, так:

Константы.<ИмяВашейКонстанты>.СоздатьМенеджерЗначения().<ИмяВашейПроцедуры>();

Но это не главное свойство этого модуля. Его самая приятная особенность в том, что в нем могуть быть описаны такие события, как:
  • ОбработкаПроверкиЗаполнения
  • ПриЗаписи
  • ПередЗаписью
(синтакс-помощник, раздел "Прикладные объекты/Константы/КонстантаМенеджерЗначения.<ИмяКонстанты>/События")

Рассмотрим событие "ОбработкаПроверкиЗаполнения". Это очень хорошее событие, чтобы убедиться в том, что константа заполнена правильно. Синтакс-помощник сообщает нам об этом событии следующее:
Вызывается расширением формы при необходимости проверки заполнения реквизитов при записи в форме, а также при выполнении метода ПроверитьЗаполнение.
Позволяет разработчику конфигурации самостоятельно реализовать проверку заполнения в обработчике события. При этом в обработчике можно полностью отказаться от системной обработки (очистив список проверяемых реквизитов), отказаться от проверки системой части реквизитов (выполнив проверку отдельных реквизитов особенным образом и исключив эти реквизиты из списка), а также добавить для проверки другие реквизиты, проверка которых не была указана.
И декларирует, что на вход функции-события передается два параметра:  <Отказ> и <ПроверяемыеРеквизиты>.
Не слишком понятное описание (как на мой взгляд) запутывающее смысл вот этим "список проверяемых реквизитов". О каком списке идет речь, если у нас одна константа? Непонятно. Очевидно, что раздел просто дублирует описание аналогичного события модуля объекта справочника, где список действительно имеется.
Однако, не будем отвлекаться. Как же проверить значение и где его (это самое значение) взять? (Если честно, я несколько поломал над этим голову, и мне кажется, что момент не вполне очевидный для начинающих). Параметром оно не передается, объекта как бы и нет...
И тут необходимо применить один из основных способов, заложенных в саму парадигму платформы 8.2:
Нужно понять в каком именно контексте вызывается событие.
Синтакс-помощник говорит нам, что событие вызывается в контексте этого самого объекта "КонстантаМенеджерЗначения.<Имя константы>", а значит, можно предположить, что свойства и методы объекта будут доступны. И действительно, следующий код прекрасно работает:

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

   
Сообщить(Значение);

КонецПроцедуры

Сообщает нам значение, которое было установлено в константу, но еще не было записано в базу (для случая, когда проверка вызывается автоматически перед записью).
Этот же контекст используется для событий "ПередЗаписью" и "ПриЗаписи".

Теперь вы можете добавить свой обработчик, который поможет проверить верно ли заполнено значение константы. Я, например, таким образом реализовал проверку на возможность изменения базовой валюты, которую нельзя менять, если в регистрах денег уже есть движения, а так же запретил константе "ВалютаПоУмолчанию" быть пустой.

Так же следует помнить, что событие "ОбработкаПроверкиЗаполнения" вызывается автоматически только при интерактивном изменении константы на форме констант. Для контроля программного изменения лучше использовать событие "ПередЗаписью", которое вызывается в обоих случаях.

Спасибо за внимание и хорошего вам кода!

среда, 21 июля 2010 г.

Assembla vs GitHub

Перевез свой rlinkf с GitHub на assembla.com
Намного удобнее и функциональнее.

вторник, 20 июля 2010 г.

Софт за 24 часа

Зарегистрировался на флешмобном сумасшествии "Софт за 24 часа". Интересно, что из этого всего получится?

воскресенье, 18 июля 2010 г.

Quick sort

Сегодня разминки ради скрипел мозгами над quick sort.

Накнопал вот такой прекрасный код:
#include <iostream>
#include <stack>

using namespace std;

void showM(int M[], int l, int r)
{
 for(int i = l; i <= r; i++) cout << M[i] << " ";
 cout << endl;
}

int main ()
{

 const int size = 8;
 int M[size] = {1,5,2,4,5,3,2,0};

 stack<int> st;

 int ret_flag = 0; int t;

 int s = 0, e = size-1;

 showM(M, 0, size-1);

func:
 int l = s, r = e;
 
 int G = M[l];

m3:
 while (M[l]<G) l++;
 while (M[r]>G) r--;

 if (l>r) goto m4;
 t=M[l]; M[l]=M[r];M[r]=t;
 l++;r--;
 goto m3;
m4:
 if(l<=r) goto m5;
 if(M[r]<=M[l]) goto m5;
 t=M[l]; M[l]=M[r]; M[r]=t;
m5:

 if(l-s <= 1) goto m1;
 st.push(s); st.push(e); st.push(l); st.push(ret_flag);
 ret_flag = 2;
 e = l-1;
 goto func;
ret2:
 ret_flag=st.top();st.pop();l=st.top();st.pop();e=st.top();st.pop();s=st.top();st.pop();

m1:
 if(e-l < 1) goto m2;

 st.push(s); st.push(e); st.push(l); st.push(ret_flag);
 ret_flag = 1;
 s = l;
 goto func;
ret1:
 ret_flag=st.top();st.pop();l=st.top();st.pop();e=st.top();st.pop();s=st.top();st.pop();
m2:

 if(ret_flag==1) goto ret1;
 if(ret_flag==2) goto ret2;

 showM(M, 0, size-1);

 return 0;
}

Поразительно, как раньше люди писали программы, когда языки не поддерживали красивую структурную вложенность? Я сломал себе половину мозга, пока реализовал это несложный алгоритм.
Отдельной проблемой было представить как правильно реализовать рекурсию без такой структуры, как "функция". Пришлось писать "болванку" с переходами для того, чтобы представить себе как рекурсивная функция должна вызываться из двух мест собственного тела.
Естественно, столкнулся с проблемой "кочующей переменной", когда значение переменной приходит из другой части кода, а не должно (забыл положить в стек L).
Опять-таки непонятно как вообще можно написать что-то существенное на языке, который не поддерживает действительноДлинныеИменаПеременных.
Вы спросите, для чего же было терпеть все эти мучения и ужас? Дело в том, что мне нужно реализовать это на ассемблере. Думаю, что такой код теперь не сложно будет перевести.

Визуализаторы базовых алгоритмов

Хотите посмотреть как мне удалось обойти самого графа?
Смотрите подробное описание каждого шага с картинками!

Там ещё много забавного и увлекательного.

пятница, 16 июля 2010 г.

Конференция "Коктейль для менеджера"

Александр Орлов и Макс Дорофеев в одном флаконе.
Любопытно, что же будет?

Подробности на http://www.dev-labs.ru/

четверг, 15 июля 2010 г.

вторник, 13 июля 2010 г.

github

Все-таки GitHub отстой. Реагирует на комиты как-то странно, путает отображение проектов. Захожу в один проект, а там исходники от другого. А где же теперь исходники от первого?
Ухожу с github.

понедельник, 5 июля 2010 г.

Мифический человеко-месяц

Забавно читать книги по IT написанные 35 лет назад. Многое изменилось на противополженое.

Например, о выпуске релизов:
Леман и Белади дают свидетельства в пользу того, что квант изменений должен быть либо очень большим и редким, либо очень маленьким и частым. (Lehman M., Belady L. Programming system dynamics, oct.1971) Последняя стратегия, согласно их модели, больше подвержена неустойчивости. Мой опыт это подтверждает: я никогда не рискну использовать ее на практике.

Или о диаграммах ПЕРТ:
Подготовка диаграммы ПЕРТ есть самая ценная часть ее применения. ... Первая диаграмма всегда ужасна, и для создания второй приходится проявить много изобретательности.

В последнем удивительно еще и то, что сам Брукс говорит о том, что такие диаграммы полезны. Но читать это можно очень по-разному.

среда, 30 июня 2010 г.

Опять Manufactoria!

Никак не могу пройти один уровень в manufactoria. Грызу, как Рональдо мяч.

Я вернулся!

И вот, после небольшого перерыва я снова с вами!

Поделюсь вкратце тем, что было. Во-первых я до-сих пор под впечатлением от AgileBaseCamp. Один из самых прекрасных докладчиков (из тех, на которых я попал, разумеется) это Александр Орлов, рулевой проекта Happy-PM и вообще мегамоск.

Вот он, в оранжевой футболке:



На доклад Тимофея Евграшина я не пошел специально, потому что предполагал попасть на его замечательный мастер-класс и перекинувшись парой слов "в кулуарах" утвердился в своем решении. Забегая вперед хочу сказать, что этот мастер-класс стал логическим завершением AgileBaseCamp.
Уже есть фотоотчет с мастер-класса, вот некоторые фото:

Мой шеф включается в работу:

Играем в спринт и планирование. Звучат страшные слова velocity и capacity:

Тим получил кружку QAClub:

И общее фото:




И еще одно фото, которого нет в альбоме. Оказалось, что мы возвращаемся с Тимофеем одним поездом.
Вокзал:

Подводя промежуточный итог могу сказать: мы многое поняли за этот день. Теперь знания нужно воплощать в жизнь, наступать на свои грабли и набивать свои шишки. Но мы не боимся сложностей, у нас есть стремление и план на ближайшее будущее. А заначит - все у нас получится.

пятница, 4 июня 2010 г.

Горы и магометы

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

P.S.: В любом случае, даже если мы придем к magile это будет существенное упорядочивание процесса.

среда, 2 июня 2010 г.

Серия статей "jQuery для начинающих"

Когда-то я писал пост о динамическом списке на jQuery и в процессе написания активно пользовался материалами из серии статей "jQuery для начинающих".
Оказывается, уважаемый автор продолжает ее писать и совсем недавно вышла статья о событиях.
Очень рекомендую саму статью и всю серию.

вторник, 1 июня 2010 г.

Manufactoria

Отличная игра для тренировки мозга - Manufactoria.
Машина тьюринга 4ever!!!

вторник, 25 мая 2010 г.

Снова статические методы классов в 1С

Я совершенно напрасно переживал по поводу статических методов классов, которых мне (и не только мне) так не хватает. В версии 1С 8.2 у объектов метаданных есть "Модуль менеджера" и функции описанные в нем фактически и являются статическими методами классов. Во всяком случае их можно так использовать.
Те, кто все понял, дальше могут не читать, с остальными давайте разберемся подробнее.

Я сделал небольшой пример. База с тремя справочниками: "Номенклатура", "КатегорииЦен" и "Цены". Номенклатура хранит список товаров, справочник "КатегрииЦен" - просто классификатор категорий, а справочник "Цены" подчинен номенклатуре и имеет два реквизита: "Категория" и "Цена" (Число). Таким образом в нем хранится цена для конкретного товара и конкретной категории. Достаточно стандартная ситуация. (Конечно, это можно организовать и регистром сведений или еще как-нибудь, но для примера я взял справочник. Просто так.)

Скачать базу можно тут: StaticMethods.zip

А теперь самое главное. Обработка "УстановитьЦены" выводит два списка: список товаров и, при выборе конкретного товара, в правом списке будут отображены его цены по каждой категории (с возможностью редактировать).
Обычно для чтения цены пишут функцию вроде "ПолучитьЦену", на вход которой передается товар и категория (а может еще и валюта, единица измерения или много чего, в зависимости от ваших нужд) а на выходе у нее полученная цена. Иногда такую функцию пишут и для записи цены.

Если с самими функциями все понятно, то вопрос где их положить до недавнего времени оставался открытым. В 7.7 такая функция скорее всего попала бы в глобальный модуль. В результате чего глобальный модуль со временем превращался в неподъемное собрание функций. Можно было всякими ухищрениями класть функции в обработки или внешние файлы или строго соблюдать структуру и принципы комментирования глобального модуля. Все-равно это все оказывалось неудобным или мало эффективным.

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

Однако, всегда хочется лучшего. Например, есть функции, которые относятся исключительно к какому-либо справочнику или документу, но нужны во всей конфигурации. Можно завести общий модуль по имени справочника, но не хотелось бы. Или можно было бы положить такие в модуль объекта. Но без объекта нельзя обратиться к модулю, а не всегда хочется тянуть целый объект из базы, когда достаточно ссылки (или ссылка вообще не нужна). Т.е. с одной стороны функции нужна привязка к "классу" объектов, а с другой, конкретный объект для работы функции не требуется. В ООП такая функция обязательно стала бы статическим методом класса, а в 1С 8.2 ее можно положить в "Модуль менеджера".
Обратите внимание на то, как я вызываю функцию "ПолучитьЦену" в обработке "УстановитьЦены":

НоваяСтрока.Цена = Справочники.Номенклатура.ПолучитьЦену(ТекущийТовар, Выборка.Ссылка);  
Через менеджер справочника. Мне не нужен лишний общий модуль или какие-то другие ухищрения.
Конечно, если говорить конкретно о функции "ПолучитьЦену", то вы могли бы поместить ее и в модуль менеджера справочники "Цены" или даже в "КатегорииЦен" или еще как-нибудь. Все зависит от того как вы строите архитектуру вашего приложения и какие используете соглашения при разработке. Но в любом случае возможность создать "статический метод класса" у вас есть. Что на мой взгляд - прекрасно.

Спасибо за внимание и хорошего вам кода.

Публикация на Infostart.