AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.07.2020, 18:03   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Почему так? new без параметров, инициализация через parm-методы
Некоторые классы следуют шаблону:
new без параметров, инициализация через parm-методы

например, класс SysClrType в ax2009, ax2012

авторы таких классов как правило еще и "закрывают" метод new модификатором protected.

вопрос:
а почему так делают? где почитать об этом шаблоне?

===============
1. знаю о сериализации/десериализации в .net
2. у таких классов как правило нет мтеодов pack/unpack (классы не реализуют интерфейс SysPackable)
3. sysDictClass.makeObject() и classFactory.createClass() игнорируют модификатор protected и вполне создают класс с "закрытым" new
4. что удивительно, у таких классов и конструктор тоже без параметров
__________________
полезное на axForum, github, vk, coub.
Старый 25.07.2020, 18:51   #2  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,510 / 435 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
А что в этом подходе плохого?
__________________
С уважением,
Вячеслав
За это сообщение автора поблагодарили: Pandasama (1).
Старый 25.07.2020, 22:11   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Я думаю это сделано для использования различных порождающих шаблонов проектирования (Порождающие шаблоны проектирования).

Для того чтобы такие объекты было удобнее создавать другим более высокоуровневые объектам, а не программистам. Точнее чтобы программистам было удобнее программировать эти высокоуровневые объекты на создание таких объектов. Ну вы поняли
За это сообщение автора поблагодарили: mazzy (2).
Старый 26.07.2020, 08:06   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от pitersky Посмотреть сообщение
А что в этом подходе плохого?
Почему плохого?

А что плохого, например, в ноже? Инструмент и инструмент. У всего есть область применения.

Лучше расскажите что хорошего.

Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Я думаю это сделано для использования различных порождающих шаблонов проектирования (Порождающие шаблоны проектирования).

Для того чтобы такие объекты было удобнее создавать другим более высокоуровневые объектам, а не программистам. Точнее чтобы программистам было удобнее программировать эти высокоуровневые объекты на создание таких объектов. Ну вы поняли
А почему такой стиль делает программное создание более удобным?

=============
Накину в обсуждение:
* стиль с parm-методами "скрывает" обязательные для объекта параметры
* стиль с parm-методами вынуждает добавлять валидацию внутреннего состояния объекта в начале каждого метода

Поясню что имею в виду.
Возьмем класс DictTable. У него в методе new явно указан обязательный для объекта параметр tableId.
Во-первых, сразу видно какой параметр обязателен.
Во-вторых, в методах класса можно не делать проверку "пропущен ли tableId", достаточно сделать такую проверку в new
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 26.07.2020 в 08:19.
За это сообщение автора поблагодарили: ta_and (4).
Старый 26.07.2020, 08:30   #5  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от mazzy Посмотреть сообщение
А почему такой стиль делает программное создание более удобным?
Создание объекта становится не атомарной операцией. Её можно разделить на этапы и ответственность за каждый этап делегировать. Появляется бОльшая гибкость.
Старый 26.07.2020, 08:34   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Создание объекта становится не атомарной операцией. Её можно разделить на этапы и ответственность за каждый этап делегировать. Появляется бОльшая гибкость.
согласен.
правда я бы опасался за термин "атомарность"
в результате может получиться полусобранный объект, в котором некоторые параметры пропущены.

собственно и вопрос - а что с таким полусобранным (не гарантированным) объектом делать?
и не превысят ли затраты на валидацию преимущества такой гибкости?

может быть, я еще каких-нибудь преимуществ не знаю?
__________________
полезное на axForum, github, vk, coub.
Старый 26.07.2020, 08:52   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от mazzy Посмотреть сообщение
собственно и вопрос - а что с таким полусобранным (не гарантированным) объектом делать?
Рассматривать такое состояние как одно из возможных состояний объекта. Т.е. решать эту проблему уже на логическом уровне, а не на транспортном.

Цитата:
Сообщение от mazzy Посмотреть сообщение
и не превысят ли затраты на валидацию преимущества такой гибкости?
Это вечный вопрос из разряда, что лучше строгая типизация или динамическая.

Нет универсального ответа. Для каждой задачи своё решение.
Старый 26.07.2020, 07:00   #8  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1633 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от mazzy Посмотреть сообщение

авторы таких классов как правило еще и "закрывают" метод new модификатором protected.
Я так понимаю чтобы использовать construct, который можно расширить
https://docs.microsoft.com/en-us/dyn...lid-principles
Цитата:
Liskov substitution – Derived classes must be able to be substituted for their base classes. For example, this substitution can be done by providing factories, by using SysExtension, and by using simple construct methods.
Старый 26.07.2020, 09:42   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Кто говорил про автогенерацию кода? Авто-генерация кода это вообще не про это.

Порождающие шаблоны проектирования - это не про генерацию кода, это про генерацию объектов.

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

Вы спрашиваете почему куча if else - это плохо?
Старый 26.07.2020, 10:14   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Кто говорил про автогенерацию кода? Авто-генерация кода это вообще не про это.

Порождающие шаблоны проектирования - это не про генерацию кода, это про генерацию объектов.

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

Вы спрашиваете почему куча if else - это плохо?
ничего не понял.

нет, я спросил то, что спросил:
Почему так? new без параметров, инициализация через parm-методы
__________________
полезное на axForum, github, vk, coub.
Старый 26.07.2020, 11:25   #11  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Цитата:
Сообщение от mazzy Посмотреть сообщение
Почему так? new без параметров, инициализация через parm-методы
1. Потому что класс может быть широко используемый, с тем или иным набором необходимых параметров. Затолкать все параметры в new() - получится мусорка, супер универсальный конструктор, который непонятно как использовать. Понятнее иметь несколько конструкторов construct*(). Яркий пример суперперегруженного конструктора у классов PrceDisc*. Каждый раз плюешься.

2. New() нельзя использовать в CoC со всеми вытекающими.

3. Чисто синтаксически, когда в коде пишеся ClassName:: - вываливается спсок всемвозможных конструкторов, из которых понятно, что больше подходит. как использовать класс.
Если написать myObject = new Object( , то вывалится 10 непонятных параметров. вдобавок, половина которых по-дефолту, а мне еще нужно установить значение десятного, повторив дэфолты тех, что в середине....

По-моему, MS рекомендовал уходить от new() в сторону consеruct() еще лет 10 тому.

Что касается методов parm() - это неудачный артефакт X++, породивший миллионы бесполезного parm-кода. К счастью, от него уже избавились в D365 в пользу модификаторов доступа.

Последний раз редактировалось DSPIC; 26.07.2020 в 11:35.
За это сообщение автора поблагодарили: mazzy (5).
Старый 26.07.2020, 12:36   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от DSPIC Посмотреть сообщение
1. Потому что класс может быть широко используемый, с тем или иным набором необходимых параметров.
ага. интересный довод. надо подумать.

Цитата:
Сообщение от DSPIC Посмотреть сообщение
Затолкать все параметры в new() - получится мусорка, супер универсальный конструктор, который непонятно как использовать.
"все" - не хорошее слово. как только появляется слово "все" жди логической ошибки
заталкивать в new конечно стоит только обязательные параметры.

Цитата:
Сообщение от DSPIC Посмотреть сообщение
Понятнее иметь несколько конструкторов construct*(). Яркий пример суперперегруженного конструктора у классов PrceDisc*. Каждый раз плюешься.
согласен. надо подумать. спасибо.

Цитата:
Сообщение от DSPIC Посмотреть сообщение
2. New() нельзя использовать в CoC со всеми вытекающими.
в смысле?
другими словами, это "достоинство new без параметров" или "недостак CoC"?

Цитата:
Сообщение от DSPIC Посмотреть сообщение
3. Чисто синтаксически, когда в коде пишеся ClassName:: - вываливается спсок всемвозможных конструкторов, из которых понятно, что больше подходит. как использовать класс.
это да.

но взгляни на тот же SysCLRType.
в нем constuct оставляет объект в полусобранном состоянии.
да, там есть newFromTypeName, который полностью инициализирует. Но зачем такой construct(), который готовит полуфабрикат?

если поискать строку 'protected void new(' в акс2009
то будет найдено порядка 1000 вхождений.
да, большинство - это старые классы, где есть конструкторы с нормальными параметрами.

Но есть и такие как SysCLRType.

Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 194
Размер:	298.9 Кб
ID:	12904

Цитата:
Сообщение от DSPIC Посмотреть сообщение
Если написать myObject = new Object( , то вывалится 10 непонятных параметров. вдобавок, половина которых по-дефолту, а мне еще нужно установить значение десятного, повторив дэфолты тех, что в середине....
Скорее в new должны быть обязательные параметры, а не все.
Да, я понял про PriceDisc.
Надо подумать.

Цитата:
Сообщение от DSPIC Посмотреть сообщение
По-моему, MS рекомендовал уходить от new() в сторону consеruct() еще лет 10 тому.
угу. еще во времена Дамгаарда

Цитата:
Сообщение от DSPIC Посмотреть сообщение
Что касается методов parm() - это неудачный артефакт X++, породивший миллионы бесполезного parm-кода. К счастью, от него уже избавились в D365 в пользу модификаторов доступа.
Ну... мысль понятна. Не буду спорить со словом "избавились" в прошедшем времени
__________________
полезное на axForum, github, vk, coub.
Старый 26.07.2020, 12:49   #13  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Справедливости ради стоит заметить, что во многих классах, в которых new защищенный так же защищенным (или приватным) является construct. А создание и инициализация выполняется методами-фабриками классов (типа newPurchInvoice и т.п.) которые конструируют и настраивают класс.
Так что какой-то проблемы вроде бы и нет. Хорошо это или плохо наверное и не сказать - ну есть такой подход.
Насколько помню, было даже время, когда Best practic ругался на код внутри метода с наименованием construct, если там было что-то помимо new.
Старый 26.07.2020, 13:04   #14  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Хорошо это или плохо наверное и не сказать - ну есть такой подход.
Если у вас есть фабрика\фабричный метод то его можно переписать (расширить в D365) и вернуть другой класс, а если вызывается new то прейдеться сначало переписать весь вызывающий код на вызов чего-то другого, что в реалиях расширений проблематично.
Старый 26.07.2020, 15:24   #15  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от skuull Посмотреть сообщение
Если у вас есть фабрика\фабричный метод то его можно переписать (расширить в D365) и вернуть другой класс, а если вызывается new то прейдеться сначало переписать весь вызывающий код на вызов чего-то другого, что в реалиях расширений проблематично.
Абсолютно верно. Я сам очень часто использую именно подход с фабричным методом (а в сложных случаях и с отдельным классом - фабрикой) именно по этим причинам.
На мой взгляд, есть просто потрясающий пример плюса данного подхода. В DAX есть семейство классов SysExcel*, работает через COM.
Уважаемый gl00mie создал семейство, работающее через более надежный NET (ну точнее COM тожеможно сделать боле-менее надежным при помощи Dispatch, но речь не про это). Переключение старого на новое потребовало только изменить фабричный метод. А вот если взять ComOfficeDocument_RU, то реализация на NET в общем-то несложная, но вот переключение на его использование уже напрягает.

Последний раз редактировалось Raven Melancholic; 26.07.2020 в 15:30.
Старый 28.07.2020, 19:56   #16  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Parm-методы это аналоги свойств в дотнете - они отличаются не только модификаторами доступа, но и тем, что внутрь можно запихнуть любую реализацию (сегодня он присваивает какое-то поле, завтра - конвертит и присваивает в другое)

Комитетов хороши тем, что без них не создашь объект. Поэтому в него хорошо передать обязательные параметры создания.

Конструкторы плохи тем что: в отличие от C# нет оверлоадов - то есть несколько конструкторов с разными наборами параметров не создашь;

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

Последний раз редактировалось belugin; 28.07.2020 в 20:03.
Старый 27.08.2020, 17:55   #17  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от belugin Посмотреть сообщение
Parm-методы это аналоги свойств в дотнете - они отличаются не только модификаторами доступа, но и тем, что внутрь можно запихнуть любую реализацию (сегодня он присваивает какое-то поле, завтра - конвертит и присваивает в другое)

Комитетов хороши тем, что без них не создашь объект. Поэтому в него хорошо передать обязательные параметры создания.

Конструкторы плохи тем что: в отличие от C# нет оверлоадов - то есть несколько конструкторов с разными наборами параметров не создашь;

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

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

В Java, кстати, считается, что если количество параметров в конструкторе больше трех, значит стоит завести класс, объединяющий некоторые поля по смыслу. Таким образом можно даже нормализовать таблицы, а также выделить в классе набор полей в единую сущность.
__________________
// no comments
Старый 27.08.2020, 18:15   #18  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Цитата:
Сообщение от dech Посмотреть сообщение
Очень жаль, что нет свойств и перегрузки методов, этого прям реально не хватает. Хорошо бы некоторые поля класса делать приватными, а не защищенными.
Все это давно уже есть и активно используется. Вот мой недавний код:
X++:
class ProdTableReservIndicatorEvaluator
{
    public ProdId                       prodId;
    public WHSReleaseStatus  releaseStatus, oldReleaseStatus;
    private boolean                    inactivated;
    ProdBOMReservIndicatorTolerance indicatorTolerance;

    public static ProdTableReservIndicatorEvaluator constuctFromProdTable(ProdTable _prodTable)
    {
        ProdTableReservIndicatorEvaluator indicatorCalc;

        indicatorCalc = new ProdTableReservIndicatorEvaluator();
        indicatorCalc.oldReleaseStatus = _prodTable.WHSReleaseStatus;
        indicatorCalc.prodId = _prodTable.ProdId;
        indicatorCalc.init();

        return indicatorCalc;
    }
}
Старый 27.08.2020, 18:40   #19  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от EVGL Посмотреть сообщение
Все это давно уже есть и активно используется.
Прошу прощения, еще не имел возможности работать в D365.
__________________
// no comments
Старый 27.08.2020, 16:43   #20  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
отвечаю сам себе:

в c# принято использовать публичные проперти.
в языке придуман специальный синтакис для инициализации публичных пропертей
https://docs.microsoft.com/ru-ru/dot...ct-initializer

в результате, в c# доступны такие конструкции для инициализации
Код:
        StudentName student4 = new StudentName
        {
            FirstName = "Craig",
            LastName = "Playstead",
            ID = 116
        };
если в классе есть приватные переменные, то их можно проинициализировать только из конструктора.
причем в конструкторе будут только позиционные параметры.

Код:
        StudentName student4 = new StudentName("private1", new DateTime(2001, 09, 11), 3.0)
        {
            FirstName = "Craig",
            LastName = "Playstead",
            ID = 116
        };

с инициализатором возможны даже такие смешные конструкции

Код:
        var team = new BaseballTeam
        {
            ["RF"] = "Mookie Betts",
            [4] = "Jose Altuve",
            ["CF"] = "Mike Trout"
        };
но хоть понятно откуда эта зараза идетЪ.

вот, что угодно, лишь бы не делать в C# именованные параметры.
https://kotlinlang.ru/docs/reference/functions.html
Цитата:
Код:
fun reformat(str: String,
             normalizeCase: Boolean = true,
             upperCaseFirstLetter: Boolean = true,
             divideByCamelHumps: Boolean = false,
             wordSeparator: Char = ' ') {
...
}
С помощью именованных аргументов мы можем сделать код более читабельным:

Код:
reformat(str,
    normalizeCase = true,
    upperCaseFirstLetter = true,
    divideByCamelHumps = false,
    wordSeparator = '_'
)
Или, если нам не нужны все эти аргументы

Код:
reformat(str, wordSeparator = '_')
При вызове функции как с позиционными, так и с именованными аргументами все позиционные аргументы должны располагаться перед первым именованным аргументом. Например, вызов f(1, y = 2) разрешен, а f(x = 1, 2) - нет.

по-любому, в X++ нет ни пропертей, ни синтаксического сахара вокруг них.
поэтому конструктор с пустыми параметрами и кучей parm-методов в Аксапте скорее нонсенс.
хотя такая конструкция может появится в интеграционном фунционале.

parm-методы в Аксаптовском функционале допустимы если в классе есть большое число параметров, как писал DSPIC.

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

Пример правильной реализации из ax2012 - метод AifWcfProcessor.createAifMessage()
Миниатюры
Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 75
Размер:	24.6 Кб
ID:	12927  
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 27.08.2020 в 17:36.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
DAX2009 почему setprefix не работает в циклах oleggy DAX: Программирование 1 03.05.2020 19:37
Печать "Без НДС" в накладной на продажу mnt_dx DAX: Функционал 4 23.01.2017 12:46
Работа с Excel через COM и ошибка 0x800A03EC (Range.AutoFilter) gl00mie DAX: Программирование 15 30.03.2007 18:37
Экспорт в эксель через XML, еще один вариант AlexeyS DAX: Программирование 6 20.09.2006 13:00
почему с pause работает, а без нее не хочет? big_bugzy DAX: Программирование 8 29.08.2006 10:59

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 17:47.