Архив рубрики: Информационные технологии

[CRM] Новые функции в Xrm.Utility появившиеся в Update Rollup 8 для Microsoft Dynamics CRM 2011

Вообще Update Rollup 8 для Microsoft Dynamics CRM вышел еще в мае, но разработчики никаким образом не заостряли внимание на изменениях в SDK. В результате мимо меня прошел тот факт, что появились JavaScript функции, недоступные ранее. И честно говоря факт их отсутствия меня порядком огорчал.

Функции были добавлены, т.к. сценарии использующие windows.open, например, из Outlook чтобы открыть форму или веб-ресурс сталкивались с тем что пользователь вынужден был повторно авторизоваться. Проблема заключалась в том что функция по сути запускала новый процесс, который не был авторизован. В обновлении были добавлены некоторые функции обертки, который во первых упростили и сделали использование таких сценариев более корректным, а во вторых исключили проблему с необходимостью повторной авторизации.

Пока что описание вызовов можно найти только на блогах разработчиков, но скоро они должны попасть в обновление SDK.

Xrm.Utility Reference

Xrm.Utility это контейнер для полезных функций, не связанных непосредственно с текущей страницей. Эти функции доступны для сценариев и для ленты (Ribbon). Для HTML веб-ресурсов, они будут доступны после подключения ClientGlobalContext.js.aspx.

Функции

Функция Описание
openEntityForm Открывает форму сущности.
openWebResource Открывает HTML веб-ресурс.

openEntityForm

Открывает форму сущности.

Xrm.Utility.openEntityForm(name,id,parameters)

Параметры

  • name (название)
    • Тип: String
    • Требует: Логическое имя сущности.
  • id
    • Тип: String
    • Опционально: Строка с уникальным идентификатором (Guid) записи, для открытия формы редактора сущности. Если оставить пустым откроется форма создания записи.
  • parameters
    • Тип: Object
    • Опционально: Объект-словарь, позволяющий передавать дополнительные параметры строки запроса. Если строка запроса будет не верна это может вызвать ошибки.Допустимые дополнительные параметры запроса:
      • Form id: Для установки идентификатора формы, когда необходимо использовать конкретную, из нескольких доступных. Параметр formid.
      • Default field ids: Устанавливает значения по умолчанию для новой записи формы. Подробнее здесь Set Field Values Using Parameters Passed to a Form.
      • Custom query string parameters: Форма может быть настроена на получение дополнительных параметров строки запроса. Подробнее здесь Configure a Form to Accept Custom Querystring Parameters.

Возвращаемое значение: Window object.

Примечание: Данная функция обесперичает наилучший способ разработки, чем простое манипалирование URL адресами через windows.open описанным здесь. Использование данной функции также позволит гарантировать отсутствие повторного окна для авторизации пользователя.

Примеры:

Открытие новой записи «Организации»

Xrm.Utility.openEntityForm("account");

Открытие существующей записи «Организации»

Xrm.Utility.openEntityForm("account","A85C0252-DF8B-E111-997C-00155D8A8410");

Открытие новой записи «Организации» с установкой значений по умолчанию и использование конкретной формы из нескольких доступных.

var parameters = {};
parameters["formid"] = "b053a39a-041a-4356-acef-ddf00182762b";
parameters["name"] = "Test";
parameters["telephone1"] = "(425) 555-1234";
Xrm.Utility.openEntityForm("account", null, parameters);

Открытие новой записки «Контакта», перемещение в верхний левый угол экрана и установка необходимого размера окна.

Примечание

Нельзя использовать методы объекта windows, такие как moveTo или resizeTo в скриптах, так как они могут быть запущены через Microsoft Dynamics CRM для Microsoft Office Outlook

var newWindow = Xrm.Utility.openEntityForm("contact");
newWindow.moveTo(0,0);
newWindow.resizeTo(800,600);

openWebResource

Открывает HTML веб-ресурс.

Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height)

Параметры

  • webResourceName
    • Тип: String
    • Требует: Название HTML веб-ресурса, который необходимо открыть.
  • webResourceData
    • Тип: String
    • Опционально: Значение которые необходимо передать в параметре data.
  • width
    • Тип: Number
    • Опционально: Ширина открываемого окна в пикселях.
  • height
    • Тип: Number
    • Опционально: Высота открываемого окна в пикселях.

Возвращаемое значение: Window object.

Примечание: HTML веб-ресур может принмать параметры описанные в Passing Parameters to HTML Web Resources .Данная функция только опеспечиваем передачу значений в параметр  data. Для передачи значений других допустимых параметров необходимо добавить их к параметру webResourceName.

Примеры:

Открытие HTML веб-ресурса под названием “new_webResource.htm”:

Xrm.Utility.openWebResource("new_webResource.htm");

Открытие HTML веб-ресурса с включением одного значение в параметр data.

Xrm.Utility.openWebResource(«new_webResource.htm»,»dataItemValue»);

Открытие  HTML веб-ресурса получающего несколько значений через параметр data.

var customParameters = encodeURIComponent("first=First Value&second=Second Value&third=Third Value");
Xrm.Utility.openWebResource("new_webResource.htm",customParameters);

Примечание

Эти значения должны быть извлечены из параметра data. Подробнее здесь Sample: Pass Multiple Values to a Web Resource Through the Data Parameter.

Открытие HTML веб-ресурса с дополнительными параметрами

Xrm.Utility.openWebResource("new_webResource.htm?typename=account&userlcid=1033");

Подробнее Passing Parameters to HTML Web Resources .

Открытие веб-ресурса с указанием ширины и высоты:

Xrm.Utility.openWebResource("new_webResource.htm", null, 300,300);

 

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

[.NET] Отладочные инструменты .NET разработчика

Очень понравилась статья с habr, позволю себе взять ее «на память» практически без изменений.

Баги встречаются на двух этапах жизненного цикла кода: во время разработки и в продакшене. Часто ошибки, которые вылезают в течение 10-15 минут с момента написания кода, мы даже не считаем за баги – они просто часть процесса написания кода. А багами мы гораздо чаще называем проблемы, которые проявляются в продакшене или при тестировании кода, написанного несколько дней назад; вероятно потому, что их сложнее отловить (код уже успел подзабыться). В любом случае, если код не делает того, что должен, это баг и его нужно отловить и исправить.

4 столпа эффективной отладки

 

  • Правильные инструменты. Это то, чему посвящена статья. Но инструменты бесполезны без других трех.
  • Использование практик построения архитектуры и кода, отдающих предпочтение слабо связанным объектам и написанию того, что я называю Совершенно Очевидный Код – СОК (Really Obvious Code – ROC rocks!). Эти практики помогают находить баги и избегать внесения изменений, лишь добавляющих новые. И никогда не поздно перечитать Brian W. Kernighan and P. J. Plauger’s «The Elements of Programming Style» (Computing Mcgraw-Hill, 1978).
  • Использование TDD (разработки через тестирование). Если вы разрабатываете что-то кроме сильно связанного пользовательского интерфейса и не используете TDD – вы разработчик с одной рукой, связанной за спиной. Вы менее продуктивны, чем могли бы быть, и ваш код менее надежен, чем должен быть.
  • Методика отладки. Многие разработчики сразу переходят к шагу «разработка решения», что в результате редко приводит к исправлению бага, зато часто создает новые.

 

Методика отладки
  1. Опишите баг. Соберите всю информацию для полного описания симптомов бага, акцентируя внимание на том, когда симптомы проявляются, а когда – нет.
  2. Зафиксируйте баг. Опишите последовательность действий, которая всегда приводит к появлению бага. Так вы убедитесь, что правильно определили условия, приводящие к появлению симптомов бага. Проверьте, что симптомы не проявляются при других условиях.
  3. Локализуйте баг. Убедитесь, что вы можете описать, в чем именно истинная причина появления бага и что описание соотносится с шагами 1 и 2.
  4. Разработайте и примените решение. Определите, боретесь ли вы с истинной причиной бага или с его симптомами. Напишите код.
  5. Проверьте решение. Проверьте, что симптомы больше не проявляются при выполнении действий, описанных в шаге 2.
  6. Проведите регрессионное тестирование. Проверьте, что не появилось новых багов.
  7. Примените изменения. Перенесите изменения в продакшен.

Использование точек останова

Многие разработчики не знают всех возможностей отладки в Visual Studio, потому что отладка «и так работает». Например, хотя каждый VS-разработчик знаком с точками останова, многие не знают, что можно сделать в окне Breakpoints.

Чтобы открыть окно Breakpoins, выберите Debug | Windows | Breakpoints; в окне отобразится список всех установленных вами точек останова. Если вы не уверены, какая точка какой строке кода соответствует, просто кликните по ней двойным кликом и в редакторе откроется связанный с ней код.

Определившись с нужной точкой, вы можете управлять тем, что происходит, когда она срабатывает. Я видел разработчиков, которые проверяют одни и те же переменные раз за разом, поставив точку останова в цикле. По правому клику на точке останова, выбрав When Hit (условие срабатывания), вы можете задать сообщение, которое выводится в окно Intermediate при каждом ее срабатывании. В сообщение можно включать некоторые константы: например, используя $Caller, можно вывести имя метода, вызвавшего код, содержащий точку останова. Также можно включить любые переменные, заключив их в фигурные скобки: например, {Me.NameTextBox.Text} в сообщении выведет значение поля Text.

Другая возможность диалога When Hit позволяет задавать, должно ли останавливаться выполнение программы на точке останова. Если выбрать остановку, то вы увидите каждое сообщение в момент его создания; в противном случае вы сможете просмотреть все сообщения после выполнения программы.

Если вы хотите остановить выполнение только при определенном условии, вы можете выбрать опции Condition или Hit Count. Опция Condition позволяет задать логическое условие, при котором произойдет остановка (например, Position > 30). Также можно выполнить остановку, если одна из переменных изменилась с момента последней остановки. Опция Hit Count прерывает выполнение только если точка останова сработала в n-й раз (или каждые n раз). Это особенно полезно, когда вам нужно остановиться где-то в конце цикла.

Между прочим, мой опыт говорит, что если в какой-то части приложения возникли проблемы, они продолжат там возникать. Если ваш опыт говорит о том же, вам понравятся дополнительные возможности Visual Studio 2010. Вы можете дать точкам останова названия, чтобы не забыть, для чего нужна каждая из них, и экспортировать их в XML-файл. В следующий раз, когда они вам понадобятся, вы можете импортировать их и начать отладку. Импорт/экспорт можно сделать с помощью тулбара вверху окна Breakpoints.

Показ и пропуск кода

Мне нравится генерирование кода (я написал книгу по тому, как это делать в .NET). Но хождение по коду, сгенерированному студией и фрэймворком, как правило не дает мне ничего полезного. А раз это не помогает найти проблему, значит делает процесс отладки менее продуктивным и лучше этого избежать.

В любой версии Visual Studio, в пункте Debug | General диалога настроек вы можете выбрать опцию Just My Code и перестать видеть код, который вы не писали. Если впоследствии вам понадобится это отключить (например, если где-то в сгенерированном коде возникает исключение), вы можете это сделать, выбрав Options and Settings в меню Debug (этот пункт есть только в VS2010 – прим. перев).

Если же вы устали ходить по какой-то части вашего кода, вы можете использовать один из двух атрибутов. Поставьте на метод атрибут DebuggerHidden и вы никогда не попадете в этот метод. Если же поставить атрибут DebuggerNonUserCode, вы не будете в него попадать при включенной опции Just My Code и будете при выключенной. Я рекомендую вам использовать второй способ.

С другой стороны, если ошибка возникает где-то в коде Microsoft .NET Framework, вам может понадобится пройти не только по сгенерированному коду, но и по коду классов фрэймворка. И вы можете это сделать! Во-первых, убедитесь, что отключена опция Just My Code. Затем в диалоге Options and Settings в разделе Symbols выберите Microsoft Symbol Server (в VS 2010) или задайте путь к символам какhttp://referencesource.microsoft.com/symbols (в VS2008). Это позволит вам загрузить символы, которые поддерживают хождение по коду классов .NET. Однако вам еще нужно их загрузить. В VS2010 вы можете кликнуть кнопку Load All Symbols, но нужно набраться терпения на время скачивания.

Чтобы выбрать конкретную сборку (или если вы используете VS2008), в режиме остановки процесса отладки откройте окно Modules и в списке DLL, загруженных вашим приложением, кликните правым кликом на нужной DLL и выберите Load Modules, чтобы загрузить символы для этой DLL. Конечно, подождать всё равно придется, но уже не так долго.

Я один из тех, кто пишет в свойствах полезный код и хочет иметь возможность пошагово их отладить. Начиная с VS2008SP1, появилась опция (Step over properties and operators), выключающая пошаговую отладку свойств и операторов. И в VS2010 она по умолчанию включена, так что вам может понадобиться ее выключить.

Визуализация данных

Как ни странно, множество разработчиков не знакомы с визуализаторами данных в Visual Studio. Если в режиме остановки навести мышку на переменную, всплывет подсказка со значением этой переменной. Также может появиться значок с лупой – клик по нему откроет значение переменной в визуализаторе по умолчанию. Если рядом с иконкой появляется стрелка выпадающего списка, клик по стрелке покажет другие визуализаторы для этого типа данных. Например, для строковой переменной будут показаны текстовый, XML и HTML визуализаторы. Если вы храните в строке HTML, HTML-визуализатор позволит понять, как это будет выглядеть в браузере.

Визуализаторы вы можете также использовать в окнах Watch, Autos и Locals, но если вы смотрите какую-то переменную очень часто, вы можете нажать на канцелярскую кнопку в конце всплывающей подсказки, чтобы «пригвоздить» ее на этом месте. Тогда в следующий раз, когда вы будете просматривать эту часть кода, подсказка всплывет автоматически.

Кстати о подсказках – вы можете с их помощью менять значение переменной. В VS2010 даже более того: подсказку можно заставить висеть в окне, существовать всё время сеанса отладки, и даже после его окончания она будет отображать значение переменной из последнего сеанса. Однако, самые крутые инструменты (Debugger Canvas и IntelliTrace) доступны только в VS2010 Ultimate Edition.

Только в VS2010 Ultimate Edition

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

Когда срабатывает точка останова, вам нужно понять, как вы здесь оказались. Можно использовать окно Call Stack, но вы не увидите, что происходило на более ранних этапах (как вариант, можно поставить кучу точек останова и проходить их последовательно, отслеживая переменные).

Если Debugger Canvas позволяет смотреть «через модули», то IntelliTrace – «через время», что дает понимание того, как вы попали в данную точку останова. IntelliTrace собирает и показывает отладочную информацию, которая была доступна в предыдущие моменты времени сеанса отладки.

Еще лучше Debugger Canvas и IntelliTrace работают в связке: в Debugger Canvas есть опция, позволяющая видеть логи IntelliTrace рядом с кодом.

Внешние инструменты

Visual Studio – не единственный инструмент отладки, есть сколько угодно внешних и сторонних инструментов, которые вы можете добавить в копилку. Я здесь остановлюсь только на некоторых бесплатных.

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

В подобной ситуации вы можете настроить Just-in-Time (JIT) отладку и автозапуск – сеанс отладки начнется, когда служба запустится или когда возникнет ошибка. Но чтобы это сделать, вам нужно воспользоваться внешними инструментами.

Так как настройка JIT-отладки выходит за рамки данной статьи, вы можете обратиться к соответствующейстатье в MSDN. Эта статья советует использовать Global Flags Editor (gflags.exe); на случай, если вы не можете его найти, описывается, как подправить реестр, чтобы включить JIT-отладку. Однако вам придется научиться пользоваться WinDbg.

WinDbg: за пределами отладчика Visual Studio

Если вам интересна отладка глубже исходного кода, Microsoft .NET Framework включает в себя несколько прекрасных инструментов.
Вот несколько из них:

  • Windows Debugger (WinDbg.exe)
  • SOS Debugging Extension (SOS.dll, которая может быть использована в консоли Visual Studio или с WinDbg.exe)
  • Assemble Binding Log Viewer (Fuslogvw.exe, который я обсуждал в блоге .NET Tips)

Если вы не использовали раньше WinDbg, это не так страшно, как может показаться – WinDbg имеет GUI (в отличие от консольных инструментов типа NTSD, KD и CBD) и может загружать PDB-файлы с отладочными символами для вашего приложения (просто убедитесь, что вы скомпилировали ваше приложение в Debug-режиме и файл символов гарантированно подходит). Вдобавок к SOS, есть еще несколько других расширений WinDbg для выполнения типичных отладочных задач.
Однако, самый полезный инструмент для использования с WinDbg – это книга Mario Hewardt, Patrick Dussud «Advanced .NET Debugging» (Addison-Wesley Professional, 2009). Она не просто рассказывает, как использовать все эти инструменты, но делает это в контексте отлавливания типичных для .NET проблем.

Сторонние визуализаторы

Я уже говорил про визуализаторы Visual Studio, но есть еще множество сторонних. DotNetDan’s DataSet Visualizer – весьма чудесен, если вам нужно знать, что лежит в датасете (я упоминал его в блоге)

С того времени я уже обнаружил RightHand DataSet Visualizer и стал использовать его. Это MDI-приложение, которое позволяет открыть окно для каждой таблицы датасета. Кроме того, окно Relations показывает таблицы, связанные с текущей просматриваемой.

Грид, отображающий таблицу, не простой – вы можете перетащить колонку в прямоугольник вверху окна, чтобы группировать вашу таблицу по этой колонке. Также можно изменять данные в датасете и менять фильтр RowState, чтобы отображались только строки с определенным RowState (например, только удаленные). Еще можно смотреть (и менять) некоторые свойства датасета. И даже можно выгрузить датасет в XML-файл или загрузить тестовые данные из сохраненного ранее.

Следует отметить, что DotNetDan’s DataSet Visualizer быстрее загружает данные, так что я оставил его на случай, когда не нужна вся мощь RightHand.

Еще есть Web Visualizer для приложений ASP.NET. Этот визуализатор доступен на всплывающей подсказке любого объекта страницы ASP.NET (включая Me и this в коде ASP.NET)

С помощью Web визуализатора можно смотреть любые данные коллекции Server Variables объекта Server и коллекции Forms объекта Request. Также можно посмотреть строку запроса браузера и содержимое объектов Session и Application. Однако, в случае Session и Application для любых объектов, кроме скалярных данных, вы увидите только название типа объекта.

Есть и другие визуализаторы, включая те, что позволяют смотреть Cache и LINQ-запросы к Entity Framework (EF), а также позволяющие увидеть SQL на выходе LINQ-запросов к EF. Печально только то, что нет единого каталога визуализаторов.

Не все, но многие можно найти через Visual Studio Extension Manager. В том числе, ASP.NET MVC Routing Visualizer. Если вы используете маршрутизацию в ASP.NET MVC или в простом ASP.NET, вам пригодится этот инструмент. Взаимодействие между правилами маршрутизации может выдавать неожиданные результаты («Почему я получаю эту страницу?»), и отладка этих правил может быть непростой. Визуализатор позволяет вам ввести URLы и посмотреть, как маршрутизатор их декодирует, включая информацию о том, какое правило используется для каждого URL. Чтобы использовать его в режиме останова, переключитесь на ваш файл global.asax и наведите курсор на RouteTable. Когдя появится всплывающая подсказка, промотайте до коллекции Routes и кликните на значок лупы.

Трассировка

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

Хотя в мире .NET для трассировки существует множество пакетов, я использую log4net. Среди прочих возможностей, log4net позволяет мне встроить в код отладочные сообщения и затем включать или отключать их во время работы без необходимости пересборки приложения. Одно замечание: log4net – очень гибкий инструмент и возможно больше, чем это требуется вам.

Когда дело доходит до чтения полученных логов, я использую Log Parser Lizard от Lizard Labs. В бесплатной версии некоторые возможности ограничены (цена платной – около 25$), однако мне они ни разу не понадобились. Log Parser Lizard использует SQL-подобный синтаксис для построения запросов к логам (включая файлы формата CSV и XML) и прямо из коробки понимает форматы логов IIS, событий Windows и log4net. Результаты отображаются в таблице, что делает его похожим на Server Explorer, с которым мне очень нравится работать.

Заключение

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

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

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

[C#] Автоматическая подстановка вариантов в TextBox

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

Идея понятна, много продуктов где есть объекты с похожим поведением, к примеру, поиск Google. Для тестового примера я решил не заморачиваться и список данных лежит в простом списке List<>, желающие смогут доделать эту реализацию для своих нужд я думаю без проблем. Логично что использовать List<> для реального продукта не имеет смысла.

В примере рассмотре пример в котором пользователь начинает вводить «Т» и получает список вариантов, по мере ввода список вариантов изменяется.

class AutoSuggestControl : TextBox
    {
        List<string> Suggestions;
        int PreviousLength; 

        // Используем простой сортированный list для предоставления вариантов.
        public AutoSuggestControl() : base()
        {
            Suggestions = new List<string>();

            // Мы сохраняем предыдущие значение длинны строки
            PreviousLength = 0; 

            // Заполняем несколько вариантов для различных ситуаций
            Suggestions.Add("Тюмень");
            Suggestions.Add("Тюменская область");
            Suggestions.Add("Тюменский район");
            Suggestions.Sort();
        }

        /// <summary>
        /// Search through the collection of suggestions for a match
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>

        private string FindSuggestion(string Input)
        {
            if (Input != "")
            foreach (string Suggestion in Suggestions)
            {
                if (Suggestion.StartsWith(Input))
                    return Suggestion;
            }
            return null;
        }

        /// <summary>
        /// We only interfere after receiving the OnTextChanged event.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);

            // We don't do anything if the user is trying to shorten the sentence
            int CursorPosition = SelectionStart;
            if (Text.Length > PreviousLength && CursorPosition >= 0)
            {
                string Suggestion = FindSuggestion(Text.Substring(0, CursorPosition));
                if (Suggestion != null)
                {
                    // Set the contents of the textbox to the suggestion
                    Text = Suggestion;
                    // Setting text puts the cursor at the beginning of the textbox, so we need to reposition it
                    Select(CursorPosition, 0);
                }
            }
            PreviousLength = Text.Length;
        }

    }
Все довольно просто и быстро. 

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Запуск приложения CookIt

Думаю, уже пора немного показать и рассказать об этом приложении.

В данный момент уже готова версия для iOS, и скриншоты Help сделаны с моего  iPhone. В первую очередь — для чего и кому нужно это приложение?

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

Работа приложения очень проста и описана Help’ом, который Вы видите, как только открываете приложение в первый раз:

1. Нажимаем кнопочку — «Добавить рецепт»

20120718-150742.jpg

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

20120718-150759.jpg

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

20120718-150808.jpg

4. Описываем процесс приготовления по шагам. К каждому шагу для наглядности можно добавить изображение.

20120718-150822.jpg

5. Теперь мы можем посмотреть на наш рецепт и узнать, какие ингредиенты нужны для его приготовления, или перейти на вкладку «Шаги» и ознакомиться с процессом приготовления.

20120718-150829.jpg
6. Очень удобная «фишка» — мы можем добавить ингредиенты любого блюда к списку покупок.

20120718-150835.jpg

7. Так же мы можем просто добавить в список покупок произвольные элементы. Например, мы внезапно выяснили, что у нас нет нужной посуды или кастрюли. Это тоже можно внести в список покупок.

20120718-150841.jpg

8. А потом, находясь в магазине, будет достаточно выбрать удобный для нас вид группировки: по рецептам или по ингредиентам.
Если выбрать по ингредиентам, то приложение просуммирует одинаковые ингредиенты из разных рецептов, и мы можем свободно передвигаться по магазину и отмечать, что мы уже положили в свою корзинку, а что еще осталось купить.

20120718-150846.jpg

Владельцы iPad и iPhone уже совсем скоро могут искать это приложение в AppStore, владельцам других устройств придется немного подождать. В скором времени расскажу о планах развития данного сервиса; думаю, любителям приготовить что-нибудь вкусное эти новости понравятся.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Работа со строковыми значениями Excel из OpenXML

Возникла задача работать с xlsx-документом из некоего приложения. Причем, нужно работать со строками и изменять их по определенным правилам.

Первая попытка была довольно наивной. Выдернуть нужную ячейку прямо по значению:

Cell cell1 = wsPart.Worksheet.Descendants<Cell>().Where(c => c.CellValue.InnerText == "name").FirstOrDefault();

Но попытка логичным образом провалилась. И это не удивительно. Если глянуть состав xmls-файла, все становится понятно.

<x:row r="5" spans="1:3" x14ac:dyDescent="0.25">
<x:c r="B5" t="s">
<x:v>1</x:v>
</x:c>
<x:c r="C5" t="s">
<x:v>2</x:v>
</x:c>
</x:row>

На самом деле, в этих ячейках не цифры «1» и «2», а строки. Об этом говорит атрибут t=’s’. В структуре xlsx-документа есть файлик под названием «SharedString». Искать эти строки стоит именно там.

Если в xlm нет атрибута t, это числа.

<x:row r="1" spans="1:3" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<x:c r="A1">
<x:v>1</x:v>
</x:c>
<x:c r="B1">
<x:v>12</x:v>
</x:c>
<x:c r="C1">
<x:v>123</x:v>
</x:c>
</x:row>

Самое смешное, что предложенный выше код ищет именно в значениях ячеек (т.е. если оно будет числовым — все будет ок), и не обращает внимания на то, что они содержат строки из SharedString. Выходит, что найти строку невозможно таким образом. Но, зато, если нам нужно работать именно со строками, задача, на самом деле, становится значительно проще.

Сам файл SharedString выглядит таким образом:

<x:sst xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="3" uniqueCount="3">
<x:si>
<x:t>troll</x:t>
</x:si>
<x:si>
<x:t>client.name.1</x:t>
</x:si>
<x:si>
<x:t>name_1</x:t>
</x:si>
</x:sst>

* This source code was highlighted with Source Code Highlighter.

И здесь искать строки можно довольно просто:

List<SharedStringItem> sharedStringItems = sharedStringPart.SharedStringTable.Descendants<SharedStringItem>().Where(s => s.InnerText == "name").ToList();

// Открывает документ с возможностью записи
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
// Проверяем есть ли в документе SharedStringTablePart. Можно работать если есть хотя бы одна.
if (document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
{
//Получаем список ShareStringTableParts
List<SharedStringTablePart> shareStringParts
= document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().ToList();
// Перебираем каждый элемент списка
foreach (SharedStringTablePart sharedStringPart in shareStringParts)
{
// Выбираем Items в которых внутренний текст имеет нужное нам значение.
List<SharedStringItem> sharedStringItems = sharedStringPart.SharedStringTable.Descendants<SharedStringItem>().Where(s => s.InnerText == "name").ToList();
...
}
}
// Сохраняем изменения в книге.
document.WorkbookPart.Workbook.Save();
}

* This source code was highlighted with Source Code Highlighter.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

MacBook Pro MC975LL

Заказал себо новое чудо инженерной мысли от Apple.

Релиза новой продукции я ждал еще с Марта месяца и вот СВЕРШИЛОСЬ.

Заказал новый MacBook Pro с Retina Display. На самом деле Retina мне особо и не интересна, а вот конфигурация в целом вызывает восхищение.

2.3GHz Quad-core Intel Core i7, Turbo Boost up to 3.3GHz
16GB 1600MHz DDR3L SDRAM
256GB Flash Storage

Зачем мне нужен MacBook?
1. Я хочу красивое устройство;
2. Я хочу устройство сделанное с умом и душой;
3. Мне нужно иметь возможность разрабатывать под Mac OS и iOS;
4. Мне нравится философия которой придерживается компания при выпуске своих продуктов.

Вообще на мой взгляд на данный момент у нового MacBook Pro не существует аналогов и конкурентов. Apple вновь создал совершенно новый рынок для себя. И об этом в принципе наглядно свидетельствует надпись Ships: 3-4 weeks на их официальном сайте. Ноутбуки расходятся как горящие пирожки, несмотря на наличие более бюджетных вариантов как у самого Apple, так и у конкурентов.

Как я понимаю сейчас мой заказ где-то на заводе и прибудет только в США где-то в середине Июля. Так что буду ждать.

Понравилась реакция Альфа-банк на крупную транзакцию. В течении 15 секунд мне позвонили, сообщили о транзакции, уточнили что все действительно верно и подтвердили. Это правильно использовать превентивные меры, вместо того чтобы потом разбираться в появившейся из ничего проблеме.

UPD: Новость про проблему с Ritena дисплеем уже видел, думаю что это должно быть решено к моменту выхода с завода моего ноутбука и проблем не будет.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Магистр

Очередная веха закончена, получен новый диплом. На этот раз «магистра Информационных Систем». Приятно.

Что изменилось за эти два года? Я выполнил множество разнообразных проектов, как в качестве исполнителя, так и в качестве куратора\руководителя. «Прокачал» множество навыков, как управления, так и собственной эффективности.

Академические знания конечно в какой-то момент времени полезны. Но! По моему мнению, самое важное заключается в том, что они должны дать умение импровизировать в нужный момент и находить решения таких задач, которые не могут взять другие.

Что дальше? Дальше работа и взгляд на аспирантуру. В этом году, скорее всего аспирантуре придется подождать, а вот в следующем штурм.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Создание вашего web-сайта, FAQ

Нужно ли Вам иметь свой веб-сайт?

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

Ну давайте разберемся по пунктам.

1. Веб-сайт это важная, неотъемлемая часть Вашей рекламной компании, вашего бизнеса.

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

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

2. Вам не придется отвлекаться на телефонные звонки от Ваших клиентов и тратить время не объяснения им чего-либо. Тут же можно указать свои контактные данные, адреса филиалов.

Если мы говорим о собственном каталоге или интернет-магазине, то вероятнее всего Вам придется звонить клиенту, выяснять у него детали, подтверждать заказ и т.п. Если мы говорим о сайте визитке или о том самом примере с сайтом эвакуатора, то Вам НУЖНО, чтобы Вам позвонили. Иначе зачем оставлять свои контакты доступными для всех.

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

Грамотность пользователей растет с каждым днем и они выбирают проверенные интернет-магазины, не хотят рисковать заказывать где-попало. Более того, в последнее время мне достаточно просто взглянуть на сайт, чтобы оценить стоит ли дальше с ним работать или можно искать другой. Конечно, иногда в такой «бан» попадают и вполне рабочие сайты. Просто они крайне бездумно реализованы, а мне, хочется голосовать рублем там, где я буду уверен в результате.

Чем является сайт на самом деле?

1. Показателем статуса и уровня Вашей компании. Зачастую, даже найдя компанию в каком-нибудь справочнике аля 2gis хочется зайти на сайт и сразу выбрать или хотя бы понять если ли у Вас то что мне нужно. Если найдутся еще 2-3 фирмы с теми же услугами, то с большей вероятностью обратятся в ту, которая имеет сайт и дает о себе информацию.

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

3. Консультантом и продавцом Вашей продукции. Это возможно и реально, но есть факторы, влияющие на успешность такой задумки.

Когда нужно делать сайт?

1. У Вашей компании большие амбиции и возможности;
2. Вы считаете что у Вас достаточно контента (информации) чтобы дать пользователю интересный материал (фото, текст, видео и т.п.);
3. Вы уверенны что Ваша продукция востребована и желаете увеличить охват рынка, чтобы продавать еще больше;
4. Вы хотите познакомить потенциальных клиентов с совершенно новой продукцией, которую никто не видел;
5. Вы понимаете что просто сделать сайт недостаточно, нужны люди которые будет его обслуживать, продвигать, рекламировать, обновлять и добавлять информацию.

Рекомандации

Мои рекомендации просты, и скорее всего банальны.
1. Не пытайтесь сделать все сами. Вы же покупаете автомобиль в автосалоне и регулярно возите его на обслуживание. Если у Вас нет электричества, Вы не лезете в щиток, а вызываете электрика. Так и здесь, есть профессионалы своего дела, которые смогут оценить Вас, Вашу информацию и потребности и предложить нужное Вам решение. Когда Вы приходите с готовым «Нужно сделать вот так и так», расписанным на несколько страниц, то они могут и сделать то что Вы просите. А Вы уверенны что именно так правильно?

2. Перед тем как собраться идти к профессионалам соберите в кучу то что имеете. Поймите что Вы можете рассказать о специфике Вашего бизнеса, есть ли у Вас материал, хотя бы на страничку «О компании» или его должен будет написать кто-то. Если у Вам необходим интернет-каталог продукции, приготовте его, например, в Excell, или каком-то другом однородном виде. Вы не получите его на сайте пока не передадите разработчикам и чем однороднее и понятнее он будет выглядеть, тем быстрее Вы увидите результаты.

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

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

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Магия дат в CRM 2011, DateTime, UTC

Поначалу я нигде не встретил такой ремарки и не обращал на этот факт внимания, пока время тестирования решения не совпало с ранним утром.

Суть заключается в том, что, выбирая на форме в поле типа Дата и Время, например, 1 мая 2012, Вы рассчитываете, что в БД так и запишется: 1 мая 2012. Но все не так просто.

CRM хранит Дату и Время в UTC, таким образом, выходит, что, если Ваш сервер находится где-то за Уралом, то время в БД будет отличаться уже более чем на 6 часов с тем, что Вы указали. Так, у меня, к примеру, получалось, что если установить дату 1 мая, то в автосгенерированном через плагин договоре ставилось 30 апреля.

В моем случае разница между DateTime, которое я ожидал получить и реальным составила 6 часов, это как раз часовой пояс Екатеринбурга.

Если бы я сразу был внимателен, то MSDN прямым текстом говорит «Specifies the attribute value in UTC format.». Сам CRM так и будет показывать в веб-форме ту дату, что Вы выбрали, но если Вы работаете с датами через плагин, то не забывайте возвращать дату из UTC в ваш часовой пояс.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Выход новых MacBook от Apple

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

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

Но вот долгожданные приятные слухи от bloomberg. Apple анонсирует новые ноутбуки уже на WWDC 2012, как, в принципе, я и ожидал. Логично: показать новые продукты уже с новой операционной системой, и все вместе.

Думаю, будет очень вкусный на новинки июнь.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.