четверг, 30 октября 2008 г.

WMI,1C,Синхронизация часть вторая

Первую задачу синхронизации работников. Я решил и успокоился, что все хватит с меня WMI. Оказалось не все так легко и просто. Встала вторая часть этой задачи, надо стало синхронизировать WMI и список подразделений.

В дереве AD подразделения были сделаны как элементы OU. И немного поштудировав MSDN я нашел, что AD для любой записи представляет интересный реквизит objectGuid. Значение которого для каждого обьекта в дереве уникально.
Из этих двух положений и станцевался кусочек кода.

P.S. Надо учитывать, что objectGuid на выходе предоставляет собой массив байт.

  1. Домен=ПолучитьCOMОбъект("LDAP://OU=YYYY,DC=ХХХ,DC=loc")
  2. // Проверка по подразделениям
  3. Для каждого объекта из Домен Цикл
  4. Для каждого класса из объекта.ObjectClass Цикл
  5.         Если НРег(класса)<>"organizationalunit" Тогда
  6.                 Продолжить;
  7.         КонецЕсли;     
  8.                
  9. НаименованиеДепартамента = СтрЗаменить(объекта.Name,"OU=","");
  10.                        
  11.         // Получим ГУИД
  12.         _ГуидДепартамента         = объекта.objectGuid;
  13.         // Теперь переведем массив байт в более понятный текстовый вид
  14.         _Гуид  = "";
  15.         _Длина = _ГуидДепартамента.GetLength(0);
  16.         Для Счетчик = 1 по _Длина-1 Цикл
  17.                 _Гуид = _Гуид + "_"+Строка(_ГуидДепартамента.GetValue(Счетчик-1)));
  18.         КонецЦикла;     
  19. // Ну а дальше уже имея на руках название подразделения и его уникальный
  20. // текстовый код, проблем быть не должно.
  21. КонецЦикла;

Примерчик работы с WMI через ADO

Встала у меня задачка надо синхронизировать содежимое ActiveDirectory и справочников 1С.

Ниже кратенький и вполне достойный пример, опроса WMI на предмет активных аккаунтов (сиречь пользователей).

P.S. А после дело синхронизации становиться легким и простым как два байта переслать. :)

  1. objConnection = ПолучитьCOMОбъект("","ADODB.Connection");
  2. objConnection.Open("Provider=ADsDSOObject");
  3. objCommand = ПолучитьCOMОбъект("","ADODB.Command");
  4. objCommand.ActiveConnection = objConnection;
  5. objCommand.CommandText =
  6. "<GC://OU=XXX,dc=YYY,dc=loc>;objectCategory=User);displayName,sAMAccountName,
  7. telephoneNumber,userAccountControl,objectGuid,distinguishedName,mail;subtree";
  8. objRecordSet = objCommand.Execute();
  9. Пока НЕ(objRecordset.EOF) Цикл
  10.  Логин = objRecordset.Fields("sAMAccountName").Value;
  11.  Почта = objRecordset.Fields("mail").Value;
  12.  Имя   = objRecordset.Fields("displayName").Value;
  13.  
  14.  Если ПустаяСтрока(Имя) Тогда
  15.   objRecordset.MoveNext();
  16.   Продолжить;   
  17.  КонецЕсли;

четверг, 16 октября 2008 г.

1C: Комплект универсальных отчетов

КонсольАнализаЖурналаРегистрации81
КонсольЗаданий
КонсольЗапросов
КонсольКластераСерверов
НастройкаТехнологическогоЖурнала

вторник, 14 октября 2008 г.

1C 8.1: Регламентные задания, маленькие хитрости

При некоторой заскорузлости описания в учебнике 1С. Документация мне так и не дала мне ответа, почему я сделал все как написано, но задание так и не запускается. Моя проблема оказалась в том, что регламентное задание запускается как внешнее соединение и в этом режиме все обращения к визуальным элементам считаются "ошибка выполнения" при этом консоль сервера не дает ответа, что случилось с запускаемым заданием. Ответ на этот вопрос дала универсальная обработка с диска ИТС "КонсольСервера", с помошью которой можно не только просматривать статистику работы запущенных задач (имхо по крайней мере, сообщение о том, что выполнение задачи было прервано на строке Х и произошла ошибка Ч, было для меня большущим подспорьем). Кроме того, ошибка может быть даже и не в процедуре регламентного задания, а в какой либо другой и увидеть это без обработки крайне сложно.

В общем подитожу:

1. Модули помеченные галочкой внешние соединение, должны содержать только те процедуры и функции которые необходимы для функционирования регламентной процедуры.

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

3. Помнить, что в случае клиент-сервера, планировщиком выступит сервер приложений, а для случая файл-сервера должен функционировать отдельное приложение, которое должно заниматься опросом:

Процедура ОбработкаЗаданий() 
    ВыполнитьОбработкуЗаданий();
КонецПроцедуры

ПодключитьОбработчикОжидания("ОбработкаЗаданий", 3);

* This source code was highlighted with Source Code Highlighter.

 

После запуска данной обработки, при открытии ее формы, выполняется подключение в качестве обработчика ожидания процедуры "ОбработкаЗаданий", которая будет вызываться каждые 3 секунды и, в свою очередь, вызывать метод "ВыполнитьОбработкуЗаданий()". Данный метод проверяет, пришло ли время выполнять задания согласно их расписанию. Если да - то он запускает эти задания на выполнение. Открытие созданной обработки по запуску регламентных заданий не рекомендуется осуществлять в том же соединении, где выполняется основная работа с информационной базой. Для подобной задачи лучше использовать отдельное соединение с той же базой. Более подробно данный вопрос освещен, например, в книге М.Радченко "1С:Предприятие 8.1. Практическое пособие разработчика. Примеры и типовые приемы", глава 12, стр.288.

вторник, 23 сентября 2008 г.

CodePlex запускает поддержку TortoiseSVN

Technorati Теги: ,,,

Оригинал статьи здесь

CodePlex теперь предлагает услуги сервера поддерживающего SvnBridge, который позволит использовать TortoiseSVN использовать для работы с Team Foundation Server. Поддержка SubVersion была одной из запрошенной пользователями фич, и поэтому хостинг SvnBridge, позволит пользователям использовать их любимые клиенты Subversion для работы с любимы проектами.

Subversion один из популярных репозитарией проектов в сообществе open source. TortoiseSVN - клиентский модуль для Subversion (так же как Team Explorer клиент для Team Foundation Server) широко распространен среди разработчиков open source. Мы хотим чтобы пользователи TortoiseSVN включились в сообщество CodePlex, и поэтому мы разработали SvnBridge, чтобы позволить TortoiseSVN работать с Team Foundation Server.

image

Наша первая версия SvnBridge требует инсталляции специального клиентского программного обеспечения, что подразумевает, что пользователи TortoiseSVN вначале инсталлируют и запустят SvnBridge прежде чем начать взаимодействовать с репозитарем CodePlex. Наличие стартовавшего SvnBridge в начале каждой сессии работы есть главный и самый раздражающий минус нашей поддержки TortoiseSVN.

Но сегодня мы с радостью сообщаем, что отныне TortoiseSVN может работать с CodePlex напрямую.

воскресенье, 21 сентября 2008 г.

C# Visual Inheritance

Мое огорчение не знает границ. Оказывается разработчики ограничили наследование не только в WPF, но и в С#. Если мы наследуем форму от базового класса, то большинство свойств таких компонентов как StatusStripPanel и ToolStripPanel становятся рид-онли.

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

P.S. Пути Майкрософт неисповедимы. В томже любимом и родном борладне еще даным давно визуальное наследование работало нормально.Будем надеяться, что спецы из майкрософта все таки справяться с этой задачкой.

понедельник, 8 сентября 2008 г.

WPF наследование

Technorati Теги: ,

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

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

P.S. Как более детально разберусь, с этими ужасными и страшными стилям, напишу очередной пост. :)

суббота, 6 сентября 2008 г.

В полку community прибавление

Technorati Теги: ,,

Еще один сайтик  Visual Studio Gallery

суббота, 9 августа 2008 г.

"Choose Folder" в WPF

Technorati Теги: ,

Очень часто мне требуется диалог с помощью которого пользователь могбы выбрать диалог на жестком диске. Но к большому сожалению в WPF не предоставляет такой функциональности. Ответ мы можем найти в пространстве имен Windows.Forms и вызовем диалог оттуда. Нижеприведенный кусочек кода демонстрирует нужную функциональность.

 

  folder

System.Windows.Forms.FolderBrowserDialog fd = new System.Windows.Forms.FolderBrowserDialog();
fd.ShowDialog();
selectedFolder.Text = fd.SelectedPath;
* This source code was highlighted with Source Code Highlighter.

среда, 6 августа 2008 г.

В полку community WPF прибавление

Technorati Теги: ,

Открылся новостной сайт аля Digg  посвященный моему любимому WPF.

http://www.dotnetkicks.com/

понедельник, 4 августа 2008 г.

Создаем закрываемые TabItem

Technorati Теги:
Шаг 1. Создадим специальный шаблон и стиль для tabitem

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

 

<TabControl>
    <TabControl.Resources>       
        <DataTemplate x:Key="CustomTabHeader">
            <StackPanel Orientation="Horizontal">
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <Binding Path="Header">
                            <Binding.RelativeSource>
                                <RelativeSource Mode="FindAncestor"
                                                AncestorType="{x:TypeabItem}"/>

                            </Binding.RelativeSource>
                        </Binding>
                    </ContentPresenter.Content>
                </ContentPresenter>
                <Button Margin="8,0,0,0" Click="OnCloseButtonClick"
                        HorizontalContentAlignment="Center"
                        VerticalContentAlignment="Center">

                    <Grid>
                        <Canvas Width="8" Height="8">
                            <Line X1="2" X2="6" Y1="2" Y2="6"
                                  Stroke="Black" StrokeThickness="1"/>

                            <Line X1="6" X2="2" Y1="2" Y2="6"
                                  Stroke="Black" StrokeThickness="1"/>

                        </Canvas>
                    </Grid>
                </Button>
            </StackPanel>
        </DataTemplate>   
        <Style TargetType="TabItem">
            <Style.Setters>
                <Setter Property="HeaderTemplate"
                        Value="{StaticResource CustomTabHeader}"/>

            </Style.Setters>
        </Style>
    </TabControl.Resources>
</TabControl>Syhi-подсветка кода
Шаг 2. Закрываем tabitem

Второй шаг потребует написания небольшого куска кода. Вот и он.

private void OnCloseButtonClick(object sender, RoutedEventArgs e)
{
    FrameworkElement parent = e.OriginalSource as FrameworkElement;

    while (parent != null && !(parent.Parent is TabItem))
    {
        parent = parent.Parent as FrameworkElement;
    }

    if (parent != null)
    {
        FrameworkElement view = (parent as TabItem).Content as FrameworkElement;
        string regionName = RegionManager.GetRegionName(view);

        _regionManager.Regions[regionName].Remove(view);
    }
}Syhi-подсветка кода
Заключение
Конечно традиционный вид tabitem может быть выглядеть более симпатичным, но с другой стороны все это не является препятствием для включение этого шаблона в своим проекты.

понедельник, 21 июля 2008 г.

ADO и ConnectionString

Technorati Теги: ,

 

ado-connection

Если вы хоть раз программировали базы данных, то знаете как бывает нелегко подобрать нужно строку коннекта для того или иного сервера. Синтаксис ADO Connection String очень простой, но, к сожалению, весьма разнообразный. А если вы пытаетесь “соединиться” с базами, которые находятся в отдельных файлах, то это совсем дело нелегкое. Специально для писателей баз данных есть исчерпывающий справочник по строкам ADO Connection, см. ниже.

Справочники по ADO Connection String:

Вот только небольшая часть баз данных, для которых подробно описана строка коннекта: SQL Server, SQL Server 2005, SQL Server 2005 Compact Edition, Oracle, MySQL, Interbase, IBM DB2, Sybase, Informix, Ingres, Mimer SQL, Lightbase, Postgre SQL, Paradox, Firebird, AS/400 (iSeries) и др.

воскресенье, 22 июня 2008 г.

WPF: MDI Окна. Часть вторая

Technorati Теги: ,

Johan спросил меня поддерживается ли MDI в Авалоне. Мы не планировали реализацию поддержки  MDI  в Авалоне версии 1, потому что MDI довольно легко реализовать средствами Windows Forms и Windows Forms interop. Я быстренько набросал небольшое демо, потратив слишком много времени чтобы в Авалоне картинка стала выглядеть более менее приемлемо, прежде чем я понял, что нет никакого способа выложить картинку в блог (гррр,гррр).
Первую вещь которую я закодил в Visual Studio, начал новый проект. Я создал простую Windows Form и задал значение IsMDIContainer = true. После я создал вторую Windows Form как дочернюю форму, и поместил в нее следующий код:

           Form f = new ChildForm();
            f.MdiParent = mainForm;
            f.Visible = true;

И это хорошо, но Авалон -- используем ElementHost. Я набросал перелестное меню и панель инструментов (креативно назвав "AvalonToolbar"), потом добавил некоторое количество кода в конструктор главного окна, чтобы поместить тулбар внутрь ElementHost, и поместить ElementHost внутрь окна:

            ElementHost host = new ElementHost();
            host.Dock = DockStyle.Top;
            host.Height = 71;

            // somewhat boneheaded way of getting Avalon content
            // into the ElementHost
            Page1 p = new Page1();
            FrameworkElement root = p.root;
            p.Child = null;
            host.AddChild(root);

            mainForm.Controls.Add(host);

Вполне возможно, лучше сделать root моего AvalonToolbar.xaml  Panel вместо Page, который поможет сохранить p.Root/p.Child = null, но по некоторым причинам я проявил упрямство. 
В итоге, я сделал несколько ElementHost в ChildForm, закрепляя разные блоки контекста Авалона внутри формы. И вуаля! MDI приложение в Авалоне с множеством тулбаров и дочерних окон. И все заняло минут пятнадцать, наибольшее время из этого ушло на изучение документации по свойству isMdiContainer (я не помню MdiParent, прошло пять лет с тех пор как я использовал WinForms).

WPF: Работа с MDI

Technorati Теги: ,

Открыв новый проект на WPF. Я обнаружил, что кудато делся мой любимый MDI - интерфейс. Недолгие поиски по интернету показали, что это все не случайно и сыр-бор идет еще с далекой первой версии "Авалона".

Lauren Lavoie в своем блоге отвечает на данный вопрос:(оригинал ответа тут)

Многие люди спрашивают почему в последнем билде WPF который мы зарелизили не включена поддержка MDI. С одной стороны, я хотел добавить это в версию 1. Но с другой стороны, я не представить себе причину по которой люди будут ждать пока мы наконецто не включим эту штуку в проект "как еще одну фичу".
Я действительно хочу сказать, что отсутствие поддержки MDI в WPF нисколько не подразумевает, что мы не думаем, что это важно. И при этом это не означает, что мы не можем добавить её в следующей версии, если не сделали её в первой версии. Есть несколько факторов, влияющих на это решение:

  • Отправляющий момент. Поскольку я уверен, что вы знаете, проекты программного обеспечения - всегда игра баланса. Баланса между одними возможностями и другими, между возможностями и патчами, между возможностью и датой выпуска продукта и т.д. MDI будет очень большой возможностью, если мы внедрим ее правильно (и разработка и внедрение подразумевает привлечение профессионалов выского класса, чтобы правильно интегрировать поддержку MDI  с существующим кодом управления стилями, системой свойств и т.д.) и в некоторой точке мы предстали перед выбором или добавить эту "большую фичу" или затянуть сроки сдачи проекта.
  • Шоколад или ваниль? Есть вероятно около двадцати "ароматов" MDI. Word делает MDI подругому чем Excel. Excel делает MDI не так как Visual Studio, а Visual Studio делает MDI совсем не так как FireFox. К томуже, я считаю, что tabbed browsing есть свой подвкус MDI. Фактически множество приложений используют своим разработки для MDI, потому что во вкусе предосталяемом API, чего не хватало каждому из разработчиков. Поэтому до того как разрабатывать, что-то такое монолитное как MDI, мы хотим удостовериться, что мы выбираем правильный аромат - или делаем это достаточно гибким способом так, чтобы наши разработчики могли настроить это, чтобы встретить их потребности. Я не думаю, что любой из нас действительно знает правильный способ сделать это все же - большая часть этого должна прибыть от понимания потребностей клиентов, которые фактически основываются на WPF (это - Вы, и следовательно спрашивать обратной связи в конце этого поста).

И так спросите вы, как же встаки использовать MDI  в вашем приложении. Не все потеряно как, кажется. Есть несколько простых способов лежащих на поверхности, годящихся на то, чтобы обойти ограничения.

  1. Использовать "Windows Forms interop". Ник Крамер описывает способ сделать это с примерами кода в своем блоге
  2. Сделать это самим. Что не так сложно как кажеться. Факт, множество приложений уже делают это сегодня, потому что их собственный вкус MDI пришел от прямоугольника в Win32/MFC/WinForms. AvPad Криса Андерсона демонстрирует менеджер дочерних окон, и Крис заявляет что его было не так сложно делать.

суббота, 21 июня 2008 г.

проба нового софта

Technorati Теги:

Установил себе новую программулину Windows Live Write. Вроде бы как обещано, оно сможет помогать делать постинги на мой любимый блог.

Ну чтож. Проверим-с. :)

З.Ы.Ж. Оказалось вполне приемлимо.

пятница, 20 июня 2008 г.

XAML: текст и картинка в кнопке

В XAML разметке по правилам можно указать только один элемент контекста для кнопки. Или текст или картинку. Но не все так плохо, как кажеться, если воспользоваться контейнерным элементом (Grid,StackPanel etc)

В итоге пример разметки будет подобным:

<Button Name="button2">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="92*" />
</Grid.ColumnDefinitions>
<Image Name="image2" Source="/ТДТ;component/Img/Close.png" Stretch="Fill" />
<TextBlock Grid.Column="1" Name="textBlock2" Text="Закрыть"/>
</Grid>

</Button>

Ангел

четверг, 19 июня 2008 г.

Начало

После долгих странствий по дневниковым хостерам, я наконецто завел себе собственный отдельный огородик. :)