<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://zine.net.pl/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Zine.net online</title><link>http://zine.net.pl/blogs/default.aspx</link><description>Serwis developerski</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>Konkurs - przywrócenie pierwotnej kolejności kolumn tabeli</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/23/konkurs-przywr-cenie-pierwotnej-kolejno-ci-kolumn-tabeli.aspx</link><pubDate>Wed, 23 Jul 2008 19:24:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1608</guid><dc:creator>mad</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;Zgodnie z obietnicą ogłaszam konkurs zapowiedziany na wczorajszej sesji PLSSUG. Zadanie polega na przywróceniu pierwotnej kolejności kolumn tabeli po usunięciu i ponownym odtworzeniu kolumny wyliczanej. Np. mamy tabelę:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.Osoby ( &lt;br /&gt;id &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;br /&gt;Imie &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(50) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;Nazwisko &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(100) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;NazwaPelna &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;as&lt;/span&gt; Imie+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;' '&lt;/span&gt;+Nazwisko, &lt;br /&gt;TelefonDoPracy &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;TelefonDomowy &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;TelefonKom &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;Telefony &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;as&lt;/span&gt;  &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonDoPracy+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;)+&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonDomowy+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;)+&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonKom+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;),&lt;br /&gt;EMail &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(100), &lt;br /&gt;DataRejestracji &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;datetime&lt;/span&gt;&lt;br /&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Po usunięciu i ponownym odtworzeniu kolumn NazwaPelna i Telefony, znajdą się one na końcu listy kolumn tabeli. Słabo napisane aplikacje mogą tej zmiany nie wytrzymać. Dlatego będziemy chcieli przywrócić kolejność pierwotną. &lt;/P&gt;
&lt;P&gt;W czasie sesji pokazałem, jak wygenerować skrypty, które dla dowolnej tabeli:&lt;/P&gt;
&lt;P&gt;1. Zapisze definicję wszystkich kolumn wyliczanych wraz z pierwotną kolejnością do tabeli &lt;BR&gt;2. Usunie wszystkie kolumny wyliczane&amp;nbsp; &lt;BR&gt;3. Odtworzy kolumny wyliczane (lądują na końcu listy)&lt;/P&gt;
&lt;P&gt;Definicja tabeli jest w skrypcie recollate.sql umieszczonych w &lt;A href="http://ms-groups.pl/communities/PLSSUG/Shared%20Documents/Forms/AllItems.aspx?RootFolder=%2fcommunities%2fPLSSUG%2fShared%20Documents%2fSkrypty%20SQL&amp;amp;FolderCTID=&amp;amp;View=%7b94539CEA%2d073B%2d47E6%2dB583%2d3F4E29D67266%7d" target=_blank&gt;zasobach&lt;/A&gt; PLSSUG. Dla wygody zacytuję ją ponownie tutaj.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.temp_ComputedCols ( &lt;br /&gt;    TableName &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt;, &lt;br /&gt;    ColumnName &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt;, &lt;br /&gt;    definition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;max&lt;/span&gt;), &lt;br /&gt;    position &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;KEY&lt;/span&gt; (TableName, ColumnName) &lt;br /&gt;    )&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Zadanie konkursowe polega na tym, żeby na podstawie definicji tabeli po operacji usunięcia i odtworzenia kolumn wyliczanych + zawartości tabeli temp_ComputedCols wygenerować skrypt, który doprowadzi tabelę do pierwotnej postaci - wszystkie kolumny są w tej samej kolejności co przed operacją. Linie skryptu mają być wygenerowane w języku TSQL w postaci procedury lub funkcji tabelarycznej. Jako jedyny parametr procedury/funkcji powinna być przekazana nazwa tabeli, dla której generujemy skrypt.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Warunki oceny rozwiązania:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;1. Rozwiązanie nie może spowodować jakiejkolwiek utraty danych w tabeli &lt;BR&gt;2. Rozwiązanie powinno wykonać minimalną liczbę manipulacji na danych i strukturze tabeli &lt;BR&gt;3. Rozwiązanie powinno przewidywać, że jest więcej niż jedna kolumna wyliczana, tak jak w przykładzie &lt;BR&gt;4. Rozwiązanie powinno być możliwie jak najszybsze&lt;/P&gt;
&lt;P&gt;Dla uproszczenia zakładamy, że w chwili rozpoczęcia naprawy na tabeli, którą mamy naprawić nie ma żadnych więzów ani indeksów.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Czekam na rozwiązania konkursowe do końca 15-08-2008 - proszę o przysyłanie ich na mój mail z profilu na wss.pl. Najciekawsze rozwiązania opublikuję, a najlepsze nagrodzę na najbliższym spotkaniu PLSSUG. Do 10.08.2008 będę poza Polską i nie wiem, czy będę miał dostęp do maila, zatem proszę nie zrażać się brakiem mojej reakcji w tym czasie.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Pozdrawiam &lt;BR&gt;Marek Adamczuk&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1608" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/TSQL/default.aspx">TSQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/konkurs/default.aspx">konkurs</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Kolumny+wyliczane/default.aspx">Kolumny wyliczane</category></item><item><title>Hash czy małpa a sprawa collation</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/23/hash-czy-ma-pa-a-sprawa-collation.aspx</link><pubDate>Wed, 23 Jul 2008 09:56:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1605</guid><dc:creator>mad</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;Wczoraj miałem przyjemność poprowadzić na PLSSUG Warszawa prezentację dotyczącą collation na SQL Serverze. W czasie prezentacji wygłosiłem pewną, nie do końca uprawnioną tezę. Mianowicie stwierdziłem, że collation z którym zakładane są domyślnie kolumny tabeli tymczasowej ustawia się na collation bazy bieżącej w SQL Server 2005 i z collation bazy tempdb w SQL Server 2000. W rzeczywistości jest to prawdą tylko dla zmiennych tablicowych. Oto przykład:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- ważne, żeby to nie było collation servera!&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;database&lt;/span&gt; bad_db &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; SQL_Polish_CP1250_CI_AS&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;use&lt;/span&gt; bad_db&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @t &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128))&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; @t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128))&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; #t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Przykład uruchamiamy na SQL Server 2000 i SQL Server 2005. Jak się okazuje, query ze zmienną tablicową wykonuje się prawidłowo tylko na 2005. Wszystkie inne zwracają błąd konfliktu collation. Zatem #tabele tymczasowe w kontekście collation nadal są złe na SQL Server 2005. Co więcej, test przeprowadzony na ostatnim dostępnym mi buildzie SQL Server 2008 daje identyczny rezultat, co 2005.&lt;/P&gt;
&lt;P&gt;Czy zatem, będąc świadomymi zła, jesteśmy w stanie mu zaradzić? Owszem jesteśmy, ale wymaga to zmiany przyzwyczajeń w pisaniu kodu. Otóż, aby być collation insensitive, musimy przy tworzeniu tabel tymczasowych, a na SQL 2000 również zmiennych tablicowych, dopisywać przy stringowych kolumnach klauzulę COLLATE database_default. Na naszym przykładzie wygląda to tak:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- tak już nie musimy robić na SQL Server 2005 i wyższych&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @t &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; database_default)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; @t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- tak niestety musimy nadal&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; database_default)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; #t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;drop&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t&lt;br /&gt;GO&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wnioski&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Jeśli nie chcemy mieć potencjalnego konfliktu collation: &lt;BR&gt;1. Dopisujemy collate database_default przy definicjach kolumn stringowych #tabel tymczasowych zawsze i zmiennych @tablicowych na SQL 2000. &lt;BR&gt;2. Jeśli mamy SQL 2005 i nie chcemy wyrabiać sobie odruchu z punktu 1 - bardziej lubimy @tabele niż #tabele. Abstrahując od innych warunków ich zastosowania, rzecz jasna.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1605" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL/default.aspx">SQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Tabela+tymczasowa/default.aspx">Tabela tymczasowa</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Collation/default.aspx">Collation</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/zmienna+tablicowa/default.aspx">zmienna tablicowa</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Resize Form czyli WinForms-y okiem laika</title><link>http://zine.net.pl/blogs/rod/archive/2008/07/21/resize-form-czyli-winforms-y-okiem-laika.aspx</link><pubDate>Mon, 21 Jul 2008 21:12:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1594</guid><dc:creator>rod</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;W WinFormsach programuje zupełnie sporadycznie. Wole warstwy domenowe, serwisowe, bazodanowe i prezentacyjne (w modelach MVP). Widoki toleruje tylko pod MonoRail i ASP.NET. Ale WinForms ? .... e to nie dla mnie. Niestety życie bywa brutalne.&amp;nbsp; W moim aktualnym projekcie integruje system finansowo księgowy z danymi dostarczanymi z działu aktuarialnego. Procesem przetwarzania danych kieruje aplikacja WinForms-owa. Prosty wygląd w postaci zakładek, gdzie dwie zakładki posiadają kontrolki na wprowadzenie parametrów. Natomiast jedna posiada textbox z zawartością logu, a jeszcze inna ReportViewer z Microsoft Reporting. &lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:6960CE03-38FC-44df-87D4-FA4540212B06:1c945c1b-c28b-4152-94eb-c414561cacc8" style="margin:0px;padding:0px;display:inline;float:none;"&gt;&lt;img src="http://zine.net.pl/photos/posts_pictures/images/1590/original.aspx" alt="" style="width:415px;height:398px;"&gt;&lt;/div&gt;  &lt;p&gt;Poprzedni programista, który projektował UI, nie uwzględnił tego aby Form był w pełni resizable a wraz z nim textbox z zawartością logu oraz ReportViewer. Mimo, że program potrafi wykonywać skomplikowane przeliczenia księgowe wg. zawiłych reguł biznesowych, łącznie z importem do systemu to brak ładnego powiększania okienka może spowodować że projekt zostanie odrzucony. Dla klienta ważniejsze jest to co widzi aniżeli to co siedzi w środku. To normalne. Lecz niestety zadanie zrobienia resizable form spadło na mnie. No to zaczynamy. &lt;a href="http://www.google.com"&gt;www.google.com&lt;/a&gt; ... "form c# resize child controls" ... press "search" ... i w sumie nic ciekawego nie znalazłem. No dobra filozofia jest przecież banalna. Jak powiększę okno o powiedzmy 100 px to pozostałe kontrolki też należy powiększyć o te 100 px. Piece of cake. Hmm, ale jak to zrobić i się nie narobić i żeby na przyszłość można było w łatwy sposób dokładać następne kontrolki, które mają reagować tak samo na powiększenie okna. &lt;/p&gt;  &lt;p&gt;Na początek należy przechować jaka jest różnica w wysokości i szerokości pomiędzy kontrolkami a oknem. Początkowo do przechowania WidthDifference i HeightDifference zrobiłem własną strukturę, ale szybko okazało się ze już jest taka struktura - Size, wiec postanowiłem ją wykorzystać. Końcowe rozwiązanie mojego problemu jest następujące. &lt;/p&gt;  &lt;p&gt;Deklarujemy pole ...&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; IDictionary&amp;lt;Control, Size&amp;gt; _sizeDifferences = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;Control, Size&amp;gt;();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;... podczas ładowania okna zapamiętujemy różnice taką metodą ...&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RememberInitialSizeDifferences()&lt;/pre&gt;

    &lt;pre class="alteven"&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    _sizeDifferences.Add(MainTabControl, this.Size - MainTabControl.Size);&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    _sizeDifferences.Add(CurrentLogTextBox, this.Size - CurrentLogTextBox.Size);&lt;/pre&gt;

    &lt;pre class="alt"&gt;    _sizeDifferences.Add(ImportSummaryReportViewer, this.Size - ImportSummaryReportViewer.Size);&lt;/pre&gt;

    &lt;pre class="alteven"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;... dodajemy metodę do eventu Resize dla obiektu Form z taką zawartością ...&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MainWindows_Resize(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var pair &lt;span class="kwrd"&gt;in&lt;/span&gt; _sizeDifferences)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        pair.Key.Size = this.Size - pair.Value;&lt;/pre&gt;

    &lt;pre class="alt"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Szybko, prosto i przyjemnie. Można się jeszcze pokusić o bardziej uniwersalne rozwiązanie i aby jakism fajnym atrybutem dekorować te kontrolki, które mają się powiększać wraz z oknem o tę sama ilośc pikseli co samo okno. Ale ... WinFormsy to nie moja działka.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1594" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/rod/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>[Ww.VS] Szablony tekstowe w VS2008</title><link>http://zine.net.pl/blogs/windywinter/archive/2008/07/21/ww-vs-szablony-tekstowe-w-vs2008.aspx</link><pubDate>Mon, 21 Jul 2008 19:43:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1591</guid><dc:creator>Wojciech Gebczyk</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;Od chwili pojawienia się DSL Tools dla Visual Studio, dostępne były szablony tekstowe&amp;nbsp;T4. Pisał o nich &lt;A href="http://zine.net.pl/blogs/arkadiusz_wasniewski/default.aspx"&gt;Arek&lt;/A&gt; w drugim &lt;A href="http://zine.net.pl/files/folders/zine2006/entry62.aspx"&gt;Zine&lt;/A&gt;. Wraz z Visual Studio 2008, bez instalowania SDK czy DSL Tools, szablony T4&amp;nbsp;są dostepne "z pudełka". Zreszta &lt;A href="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/2008/07/20/refaktoryzacja-metod-zwrotnych.aspx"&gt;ostatni wpis na blogu&lt;/A&gt; Arka (ten w ktorym używa takich skomplikowanych zwrotów jak refaktoryzacja czy metoda zwrotna kojarząca mi się z kolejami).&lt;/P&gt;
&lt;H4&gt;Jak najszybciej użyć T4?&lt;/H4&gt;
&lt;P&gt;Poprostu należy dodać plik o rozszerzeniu tt do projektu i VS2008 automatycznie podłączy CustomTool "TextTemplatingFileGenerator" i wygeneruje podłączony plik cs.&lt;/P&gt;
&lt;P&gt;Wystarczy teraz w pliku napisać cos takiego:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; MyApp {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; Class1 {&lt;br /&gt;&amp;lt;# &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;foreach&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Aaa"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Bbb"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Ccc"&lt;/span&gt; }) { #&amp;gt;&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; &amp;lt;#&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; name #&amp;gt; { get; set; }&lt;br /&gt;&amp;lt;# } #&amp;gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Aby otrzymać taki wynik:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; MyApp {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; Class1 {&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Aaa { get; set; }&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Bbb { get; set; }&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Ccc { get; set; }&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;H4&gt;Parę uwag przy dodawaniu szablonów T4&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Za pierwszym razem możemy dostać ostrzerzenie "Security Warning" informujące o niebezpieczeństwie zniszczenia komputera pewnie razem z księżycem. Najlepiej potwierdzić za pomocą OK, zaznaczając wczesniej CheckBox "Do not show this message again". 
&lt;LI&gt;Plik tekstowy bez dyrektyw szablonu (znaczników na początku pliku &amp;lt;#@ i #&amp;gt;) czy znaczników renderowania, również jest poprawnym szablonem, który generuje tekst identyczny z zawartościa szablonu 
&lt;LI&gt;Wygodnie jest dodac nowy szablon za pomocą opcji "Add&amp;gt;New Item...", wybrać dowolny tekstowy plik jak Class czy Code File zmieniając rozszerzenie pliku na ".tt" zamiast ".cs" 
&lt;LI&gt;Standardowo plik generowany pod szablonem ma rozszerzenie ".cs" (to w przypadku projektów C#, zapewne w przypadku projektów VB będzie to ".vb" - nie sprawdzałem). Wiąże się to również z tym że zachowanie pliku w projekcie będzie takie jak typowego pliku o tym rozszerzeniu - w przypadku plików ".cs" "Build Action" będzie ustawiony na "Compile". 
&lt;LI&gt;Jesli wybierzemy inny plik (na przykład XML File), to standardowo dostaniemy wygenerowany plik ".cs". Generowane rozszerzenie można zmienić dodając dyrektywę output na przykład tak: &amp;lt;#@ output extension="xml" #&amp;gt; - koniecznie na początku pliku! 
&lt;LI&gt;Jesli plik szablonu o rozszerzeniu ".tt" skopiowany do schowka (na przykład z pulpitu, czy Exploratora Windows) wkleimy do projektu, to również poprawnie zarejestruje nam sie szablon. 
&lt;LI&gt;Jesli istniejącemu plikowi (na przykład ".cs") zmienimy rozszerzenie na ".tt", to znowu otrzymamy działający plik szablonu. Jedyna niedogodnościa może być to że wygenerowany plik pod szablonem będzie miał w nazwie suffix "1" (lub inna cyfrę). Można tego uniknąć stosując inną metodę, lub ręcznie edytując plik projektu ".csproj" (Unload Project a potem Edit) i usuwając element "LastGenOutput" z elementu odpowiadającego szablonowi. Po ponownym załadowaniu należy usunąć poprzednio wgenerowany plik i wymusić generację ponownie (opcja Run Custom Tool).&lt;/LI&gt;&lt;/OL&gt;
&lt;H4&gt;Mały bonus&lt;/H4&gt;
&lt;P&gt;&lt;A href="http://zine.net.pl/files/folders/1593/download.aspx"&gt;W archiwum ZIP&lt;/A&gt;, znajdują się 4 pliki szablonów. Wystarczy je rozpakować, skopiować i wkleić do projektu, aby otrzymać parę klas "utilsowych".&lt;/P&gt;
&lt;P&gt;Guard i GuardDebug - to klasy podobne do Assert, lecz posiadające API bazujące na xUnit.&lt;/P&gt;
&lt;P&gt;Entries - to zbiór prostych klas-pojemników, do zastosowań wewnątrz implementacyjnych (nie zalecane "wystawianie" tych typów w publicznym API).&lt;/P&gt;
&lt;P&gt;Przykładowe użycie:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Guard.NotNull(param1, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Param1 cannot be null."&lt;/span&gt;);&lt;br /&gt;GuardDebug.NotNullOrEmpty(name, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Entity name cannot be empty."&lt;/span&gt;);&lt;br /&gt;var e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Entry&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;(1, 2, 3);&lt;br /&gt;Guard.InRange(e.Value2, e.Value1, e.Value3, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Entry constraint not satisfied."&lt;/span&gt;);&lt;br /&gt;var map &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;, Entry&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Jeśli macie jakieś uwagi zapraszam do komentowania lub kontaktu mailowego.&lt;/P&gt;
&lt;P&gt;Oczywiscie standardowy disclaimer ze nei odpowiadam za problemy, wybuchy etc.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1591" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/Text+Template/default.aspx">Text Template</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/Text/default.aspx">Text</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/Template/default.aspx">Template</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/Szablon/default.aspx">Szablon</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/Custom/default.aspx">Custom</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/VS/default.aspx">VS</category><category domain="http://zine.net.pl/blogs/windywinter/archive/tags/VS2008/default.aspx">VS2008</category></item><item><title>Ikonki Tortoise SVN w Total Commander</title><link>http://zine.net.pl/blogs/procent/archive/2008/07/21/ikonki-tortoise-svn-w-total-commander.aspx</link><pubDate>Mon, 21 Jul 2008 19:08:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1589</guid><dc:creator>Procent</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;Czy jest ktoś kto nie zna/nie używa Total Commandera? Nie? Tak myślałem. A czy jest ktoś, kto po &lt;a href="http://www.maciejaniserowicz.com/post.aspx?id=03c9d7cb-cb40-4469-86d4-66dc392617cf"&gt;moim pięknym kazaniu&lt;/a&gt; nie używa Tortoise SVN? Też nie, gut.&lt;/P&gt;
&lt;P&gt;Przykro mi było, gdy korzystanie z tych dwóch cudnych kawałów softu nie dawało takiego komfortu jakiego bym oczekiwał, a to za sprawą braku wyświetlania ikonek Tortoise w Commanderze. O ileż lepiej i bardziej funkcjonalnie przedstawiał się widok katalogu w zwykłym Windows Explorerze:&lt;/P&gt;&lt;IMG alt="" src="http://zine.net.pl/photos/posts_pictures/images/1586/original.aspx"&gt; 
&lt;P&gt;Okazało się jednak, że to po części moja własna wina. Z pewnych powodów byłem bardzo przyzwyczajony do Windows Commander w wersji 5.0 i tam faktycznie nic się nie dało z tym zrobić. Wystarczyło jednak wykonać upgrade do Total Commander 7, zaznaczyć jedną opcję...&lt;/P&gt;&lt;IMG alt="" src="http://zine.net.pl/photos/posts_pictures/images/1587/original.aspx"&gt; 
&lt;P&gt;...i cieszyć oczy wspaniałą symbiozą TC+SVN!&lt;/P&gt;&lt;IMG alt="" src="http://zine.net.pl/photos/posts_pictures/images/1588/original.aspx"&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1589" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/procent/archive/tags/tools/default.aspx">tools</category></item><item><title>Refaktoryzacja metod zwrotnych</title><link>http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/2008/07/20/refaktoryzacja-metod-zwrotnych.aspx</link><pubDate>Sat, 19 Jul 2008 22:57:32 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1572</guid><dc:creator>arkadiusz.wasniewski</dc:creator><slash:comments>10</slash:comments><description>&lt;p&gt;Najnowsza refaktoryzacja kodu jednego z moich projekt&amp;#243;w polegała na usunięciu wszystkich własnych definicji delegat&amp;#243;w będących metodami zwrotnymi. Zamiast tego użyłem standardowych metod z przestrzeni nazw &lt;strong&gt;System&lt;/strong&gt;:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.action.aspx"&gt;Action&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx"&gt;Action&amp;lt;T&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549311.aspx"&gt;Action&amp;lt;T1, T2&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549392.aspx"&gt;Action&amp;lt;T1, T2, T3&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb548654.aspx"&gt;Action&amp;lt;T1, T2, T3, T4&amp;gt;&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;dla metod zwrotnych, kt&amp;#243;re nie zwracają wartości oraz:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx"&gt;Func&amp;lt;TResult&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549151.aspx"&gt;Func&amp;lt;T, TResult&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534647.aspx"&gt;Func&amp;lt;T1, T2, TResult&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549430.aspx"&gt;Func&amp;lt;T1, T2, T3, TResult&amp;gt;&lt;/a&gt;;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534303.aspx"&gt;Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt;&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;dla metod zwrotnych zwracających wartość.&lt;/p&gt;  &lt;p&gt;Dzięki temu zniknęło kilka klas. A sam kod wbrew pozorom stał się bardziej przejrzysty przez to, iż nie trzeba zastanawiać się jak wygląda metoda &lt;font color="#2b91af"&gt;WorkflowTerminateCallback&lt;/font&gt; jeśli teraz w kodzie występuje wywołanie metody &lt;font color="#2b91af"&gt;Action&lt;/font&gt;. Wbrew pozorom, ponieważ nazwa metody &lt;font color="#2b91af"&gt;WorkflowTerminateCallback&lt;/font&gt; jest bardziej wymowna od metody &lt;font color="#2b91af"&gt;Action&lt;/font&gt; i niepokoiło mnie, czy przypadkiem źr&amp;#243;dła nie staną się mniej przejrzyste. Kod żyje jednak w pewnym kontekście i po wprowadzeniu zmian okazało się, iż moje obawy były bezzasadne.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1572" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/tags/Metodyka/default.aspx">Metodyka</category><category domain="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/tags/Wzorce+projektowe/default.aspx">Wzorce projektowe</category><category domain="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/tags/.NET/default.aspx">.NET</category></item><item><title>[EN] Five things I would change in SSMS</title><link>http://zine.net.pl/blogs/sqlgeek/archive/2008/07/19/en-five-things-i-would-change-in-ssms.aspx</link><pubDate>Sat, 19 Jul 2008 16:12:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1570</guid><dc:creator>brejk</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;SQL Server Management Studio (SSMS) is the most often used environment in my everyday work. I got used to all those dockable windows and I stopped complaining about the loading time or the clipboard smaller than the one in Query Analyzer (QA) - at least it seems to be smaller :-) But there are some things that are quite annoying to me. Here are my five most wanted changes to implement in SSMS by Microsoft’s developers.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Custom keyboard shortcuts working in Results and Messages windows&lt;/STRONG&gt;. I use those shortcuts a lot and I really miss the old behavior from QA. 
&lt;LI&gt;&lt;STRONG&gt;Persistent windows numbers in Window menu&lt;/STRONG&gt;. When working with multiple windows in QA I have been using Alt+W and then Alt+&amp;lt;&amp;lt;Number&amp;gt;&amp;gt; to switch to another window. In SSMS this feature works slightly different because the active query window has always number 1 which makes the numbers dynamic and it becomes impossible to remember the numbers (it’s impossible to remember something that changes everytime you use the shortcut...). Anyway, Microsoft folks claim this behavoir is identical with the one from Visual Studio and is not going to be changed... 
&lt;LI&gt;&lt;STRONG&gt;Filters on databases in Object Explorer&lt;/STRONG&gt;. This problem does not touch me explicitly. But sometimes there are many databases on the instance and finding the proper database with Object Explorer window in SSMS can be very painful. Also, filters could remain active when user re-opens SSMS. In SQL Server 2008 there is a new feature called Object Search but it can be used with Object Explorer Details window and it can search for database objects only (you can’t find the database this way). Besides, this new search mechanism need some improvement also, because it is unable to find an object when you enter a qualified object name. There is an article on how to create an add-in for enhanced object filtering in SSMS (including databases) written by Joseph Cooney - &lt;A href="http://jcooney.net/archive/2007/11/26/55358.aspx"&gt;The Black Art of Writing a SQL Server Management Studio 2005 Add-In&lt;/A&gt;. 
&lt;LI&gt;&lt;STRONG&gt;Automatic or semi-automatic refresh in Object Explorer. &lt;/STRONG&gt;This problem seems to have a beard already. When you perform any action outside the Object Explorer window even collapsing and expanding of the proper folder in this window do not refresh the tree (you have to perform right-click and Refresh which makes me mad). 
&lt;LI&gt;&lt;STRONG&gt;Changes in options do not require the application restart&lt;/STRONG&gt;. Sometimes (especially during presentations) I have to change some options in SSMS. I feel very uncomfortable with the requirement of the application restart after some small changes like font size of grid results. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Do this changes have some chances to be implemented? Well, I guess they are not very hard to add! Some of them have been posted to connect.microsoft.com as suggestions. See the links below.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=250392"&gt;Management Studio - Windows List Order&lt;/A&gt; (status: closed)&lt;/P&gt;
&lt;P&gt;&lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=235081"&gt;Customize Keyboard stored procedures do not work in results pane in SSMS&lt;/A&gt; (status: closed)&lt;/P&gt;
&lt;P&gt;&lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=127004"&gt;Expand the Management Studio Object Explorer Filter&lt;/A&gt; (status: closed)&lt;/P&gt;
&lt;P&gt;&lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=125666"&gt;Refreshing Object explorer&lt;/A&gt; (status: closed)&lt;/P&gt;
&lt;P&gt;Finally, I’m not as frustrated as the author of this suggestion: &lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=240418"&gt;Usability of Management Studio is worst between all DB managers&lt;/A&gt; (see Proposed Solution – my favourite :-)). However, it would be nice to see some of the wishes listed above added to SSMS in SQL Server 2008 or some of its Service Packs, wouldn’t it?&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;If you have any suggestion or most wanted things to repair or to implement in SSMS, feel free to post a comment to this note.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1570" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/sqlgeek/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/sqlgeek/archive/tags/Management+Studio/default.aspx">Management Studio</category><category domain="http://zine.net.pl/blogs/sqlgeek/archive/tags/SSMS/default.aspx">SSMS</category><category domain="http://zine.net.pl/blogs/sqlgeek/archive/tags/tools/default.aspx">tools</category></item><item><title>Bug w SharePoint Designer?</title><link>http://zine.net.pl/blogs/gutek/archive/2008/07/17/bug-w-sharepoint-designer.aspx</link><pubDate>Thu, 17 Jul 2008 14:09:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1564</guid><dc:creator>Gutek</dc:creator><slash:comments>2</slash:comments><description>&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Dziś natrafiłem na nietypowe zachowanie SharePoint Designer. Podczas tworzenia własnego z modernizowanego view na listę poprzez konwersję List View Web Part do XSLT Data View Web Part, linki do elementów uległy zmianie.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Mianowicie, standardowy List View Web Part wyświetlał nazwy raportów Excel, które są wyświetlane za pomocą Excel Services. Kliknięcie na raport przekierowuje do strony znajdującej się w katalogu leyaouts – xlsviewer.aspx, która jaki query string przyjmuje link do pliku Excel. W kodzie źródłowym strony możemy zauważyć iż przekserowanie wykonywane jest przez funkcję OnLick na tag’u &amp;lt;A&amp;gt;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;onfocus&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="OnLink(this)"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;HREF&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="/OddsOn/ReportsLibrary/Report.xlsx"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;onclick&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3'&lt;BR&gt;,'1','SharePoint.OpenDocuments','',&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="COLOR:blue;"&gt;'1http:\u002f\u002flsharepoint\u002fOddsOn\u002f_layouts&lt;BR&gt;\u002fxlviewer.aspx?&lt;BR&gt;id=\u002fOddsOn\u002fReportsLibrary\u002fReport.xlsx'&lt;BR&gt;,'','2','0','0','0x7fffffffffffffff')"&amp;gt;&lt;/SPAN&gt;Report&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:#a31515;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Funkcja DispEx przyjmuje następujące parametry:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;ele&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Element którego tyczy dany kod. Tak naprawdę nie jest on wykorzystywany przez &lt;B style="mso-bidi-font-weight:normal;"&gt;DispEx&lt;/B&gt;, ale jest przekazany do kolejnej metody wywoływanej przez DispEx. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;objEvent&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Obiekt event, do którego będą podpinane zdarzenia.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;fTransformServiceOn&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Wartość Boolean, określająca czy dany dokument ma być poddany transformacji. Np.: w naszym przypadku czy Excel ma zostać wyświetlony za pomocą Excel Services.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;fShouldTransformExtension&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;- Szczerze mówiąc nie wiem co to dokładnie jest, nie jest to prawie wykorzystywane oprócz jednego IF’a, w którym również nie jest zbyt dużo powiedziane. Przypuszczam, że jeżeli się stworzy własny konwerter na podstawie konwerterów dostarczonych w MOSS, to będzie miało wtedy ręce i nogi.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;fTransformHandleUrl&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Patrz wyżej.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strHtmlTrProgId&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Element służy do oznaczenia, że MOSS jest wstanie przekształcić i otworzyć samemu dany dokument. Tak naprawdę, element ten może być równy &lt;B style="mso-bidi-font-weight:normal;"&gt;strHtmlType&lt;/B&gt;. SharePoint sam doda .3 do końcówki.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;iDefaultItemOpen&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Jeżeli zostanie podana wartość 1, to MOSS wykorzysta parametr strServerFileRedirect by otworzyć dany element w MOSS. Jakakolwiek inna wartość zostanie zignorowana.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strProgId&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Informacja dla MOSS, że to on powinien otworzyć dokument. W tym wypadku nie możemy podać .3, gdyż z automatu to jest dodawane bez sprawdzenia czy istnieje. Mianowicie MOSS tworzy obiekt ActiveX o nazwie „SharePoint.OpenDocuments.3”.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strHtmlType&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Dla dokumentów Excel czy Word, musi być null, w innych wypadkach można podać tym dokument – np.: SharePoint.WebPartPage.Document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strServerFileRedirect&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – URL zaczynający się od dowolnego jednego znaku. To znaczy, że zanim podamy URL gdzie chcemy by nas funkcja przekserowała podajemy np.: 1 lub 2 lub a, cokolwiek by odciąć możliwość wyciągania łatwego URLi. MOSS sam zadba o to by ten pierwszy znak usunąć.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strCheckoutUser&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Użytkownik, który wyczekaoutował dokument.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strCurrentUser&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – ID aktualnego użytkownika.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strRequireCheckout&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Informacja, która mówi MOSS, że przy otwarciu/edycji ma z powodować check out dokumentu. Wartość 1 oznacza, że tak. Każda inna, że nie.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strCheckedoutTolocal&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Oznacza czy dokument został wyczekaoutowany czy nie. Wartość 1 oznacza, że tak. Zaś każda inna, że nie.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN:0cm 0cm 10pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:Symbol;mso-ansi-language:PL;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;strPermmask&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt; – Maska uprawnień do elementu.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Teraz, kiedy taki widok otworzymy sobie w SharePoint Designer i klikniemy na nie prawym przyciskiem myszy, dostaniemy możliwość przekonwertowania go do XSLT Data View Web Part.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;o:p&gt;&lt;IMG src="http://zine.net.pl/photos/posts_pictures/images/1563/original.aspx"&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Jeżeli taki widok zapiszemy w katalogu Forms od naszej biblioteki, będzie on dostępny z menu Views na liście. No to od słów do czynu. Konwertujemy List View Web Part, zapisujemy zmiany i otwieramy View na stronie MOSS. Niestety, od razu czeka nas niemiła niespodzianka. Mianowicie nasz link przestał działać! Teraz zamiast renderowania raportu w Excel Services, pojawia nam się śliczne okienko z zapytaniem czy ściągnąć dokument, otworzyć go czy anulować operację.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;o:p&gt;&lt;IMG src="http://zine.net.pl/photos/posts_pictures/images/1562/original.aspx"&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Dzieje się tak, gdyż SharePoint Designer konwertuje nasz tag &amp;lt;A&amp;gt; do następującej postaci:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;onfocus&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="OnLink(this)"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;HREF&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="{@FileRef}"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;onclick&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="return DispEx(this,event,'',&lt;BR&gt;'','','','{ddwrt:ListProperty(&amp;amp;quot;DefaultItemOpen&amp;amp;quot;)}'&lt;BR&gt;,'{ddwrt:MapToControl(&amp;amp;quot;&amp;amp;quot;, string())}'&lt;BR&gt;,'{@HTML_x0020_File_x0020_Type}',''&lt;BR&gt;,'{ddwrt:GetUserID('CheckoutUser')}','{$Userid}'&lt;BR&gt;,'{ddwrt:ListProperty(&amp;amp;quot;ForceCheckout&amp;amp;quot;)}'&lt;BR&gt;,'{$FieldIDAY3AFD}'&lt;BR&gt;,'{ddwrt:CurrentRights()}')"&amp;gt;&lt;/SPAN&gt;...&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:#a31515;"&gt;a&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Od razu można zauważyć iż nie korzystamy z usług transformacyjnych, a parametr strServerFileRedirect nie jest nawet podany. Niestety, nie tylko to się dzieje. Jak otworzymy sobie nasz widok za pomocą podglądu źródła strony zobaczymy, że na stronie wygląda to tak:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;onfocus&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="OnLink(this)"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;HREF&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="/OddsOn/ReportsLibrary/Report.xlsx"&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR:red;"&gt;onclick&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="return DispEx(this,event,'','','','','','',''&lt;BR&gt;,'','','2','','0','7FFFFFFFFFFFFFFF')"&amp;gt;&lt;/SPAN&gt;Report&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:#a31515;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Tak jak już wiemy, część parametrów nie trzeba podawać gdyż MOSS się sam nimi zajmie, jednak część trzeba podać. Do nich na pewno możemy zaliczyć pierwsze 10 parametrów.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Jednak nic straconego ;) wystarczy, że kod za pomocą SharePoint Designer zamienimy na:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;onfocus&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="OnLink(this)"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;HREF&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="/OddsOn/ReportsLibrary/Report.xlsx"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;onclick&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','1'&lt;BR&gt;,'SharePoint.OpenDocuments',''&lt;BR&gt;,'1http:\u002f\u002fladsharepoint\u002fOddsOn\u002f_layouts&lt;BR&gt;\u002fxlviewer.aspx?&lt;BR&gt;&lt;A href="mailto:id={@ServerUrl}','{ddwrt:GetUserID('CheckoutUser')}','{$Userid}'"&gt;id={@ServerUrl}','{ddwrt:GetUserID('CheckoutUser')}','{$Userid}'&lt;/A&gt;,&lt;BR&gt;'0','{$FieldIDATD1BB}','{ddwrt:CurrentRights()}')"&amp;gt;&lt;/SPAN&gt;Report&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:#a31515;"&gt;A&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;I wszystko będzie nam śmigać :) Zwróćcie uwagę na link w strServerFileRedirect, jako że musicie go dopasować do swojego adresu.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;PS.: Jeżeli się pobawicie różnymi kolumnami, to zobaczycie, że tych Bugów jest więcej. Na przykład, jeżeli wykorzystacie kolumnę &lt;I style="mso-bidi-font-style:normal;"&gt;Name linked to report&lt;/I&gt; to po konwersji będziecie mieli taki błąd:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;o:p&gt;&lt;IMG src="http://zine.net.pl/photos/posts_pictures/images/1561/original.aspx"&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Jeżeli zaś wykorzystanie kolumnę Edit (czyli link do edycji elementu), to nawet nie uda wam się poprawnie przekonwertować widoku.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1564" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/gutek/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://zine.net.pl/blogs/gutek/archive/tags/SharePoint+Designer/default.aspx">SharePoint Designer</category><category domain="http://zine.net.pl/blogs/gutek/archive/tags/Bug/default.aspx">Bug</category></item><item><title>Tips &amp; Tricks 03: JavaScript na Body OnLoad w SharePoint</title><link>http://zine.net.pl/blogs/gutek/archive/2008/07/17/tips-tricks-03-javascript-na-body-onload-w-sharepoint.aspx</link><pubDate>Thu, 17 Jul 2008 13:12:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1560</guid><dc:creator>Gutek</dc:creator><slash:comments>0</slash:comments><description>&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Czasami podczas dostosowywania SharePoint do własnych potrzeb wynika potrzeba dodania metody JavaScript, która powinna uruchomić się w momencie załadowania strony.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Można to osiągnąć bardzo prosto, wystarczy, że wywołamy następujący kod:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-ansi-language:PL;mso-no-proof:yes;"&gt;_spBodyOnLoadFunctionNames.push(&lt;SPAN style="COLOR:#a31515;"&gt;'NazwaFunkcji'&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:PL;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;a SharePoint zajmie się resztą ;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1560" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/gutek/archive/tags/Tips+_2600_amp_3B00_+Tricks/default.aspx">Tips &amp;amp; Tricks</category><category domain="http://zine.net.pl/blogs/gutek/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://zine.net.pl/blogs/gutek/archive/tags/WSS+3.0/default.aspx">WSS 3.0</category></item><item><title>Automatyzacja projektu z MSBuild-em - 4a. TDD, prawie jak TestDriven.NET</title><link>http://zine.net.pl/blogs/rod/archive/2008/07/17/automatyzacja-projektu-z-msbuild-em-4a-tdd-prawie-jak-testdriven-net.aspx</link><pubDate>Thu, 17 Jul 2008 12:51:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1559</guid><dc:creator>rod</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Wcześniej już wspominałem, jestem strasznie leniwy. Nie lubię pokonywać setek kilometrów myszką, nie lubię pisać dwa razy tego samego, nie lubię często naciskać Alt+Tab ... i wpadłem na taki pomysł.&lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;div class="wlWriterSmartContent" id="scid:6960CE03-38FC-44df-87D4-FA4540212B06:e8a9c5bf-6229-48c9-a2ce-0c3cd664900a" style="margin:0px;padding:0px;display:inline;float:none;"&gt;&lt;img src="http://zine.net.pl/photos/posts_pictures/images/1555/original.aspx" alt="" style="width:396px;height:391px;"&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;div class="wlWriterSmartContent" id="scid:6960CE03-38FC-44df-87D4-FA4540212B06:076a4249-b86f-46e6-96af-9b205073074f" style="margin:0px;padding:0px;display:inline;"&gt;&lt;img src="http://zine.net.pl/photos/posts_pictures/images/1557/original.aspx" alt="" style="width:396px;height:391px;"&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Teraz wystarczy zamapować klawisze, np...&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:6960CE03-38FC-44df-87D4-FA4540212B06:1bf5ee3e-5689-42ce-8cc4-4027d04ea3e1" style="margin:0px;padding:0px;display:inline;"&gt;&lt;img src="http://zine.net.pl/photos/posts_pictures/images/1558/original.aspx" alt="" style="width:403px;height:250px;"&gt;&lt;/div&gt;  &lt;p&gt;... i prawie jak TestDriven.NET :)&lt;/p&gt;  &lt;p&gt;A teraz mała opowiastka ... Ostatnio, w trakcie rozmowy rekrutacyjnej w ramach poszukiwania pracy, spytałem osobę, która&amp;nbsp; przeprowadzała ze mną wywiad, czy w swoich projektach wykorzystują TDD. Okazało się, że chcieliby, ale tak nie do końca bo mają testy własne napisane we frameworku X, który znają, a dostali jeszcze w spadku poprzednia wersję, którą miała napisane testy we frameworku Y i niby teraz trzeba by przepisać te testy a nie ma czasu etc etc ?!?!?&lt;/p&gt;  &lt;p&gt;Ja wychodzę z założenia że lepsze unit testy jakiekolwiek, niż żadne. Framework się nie liczy. Oczywiście nie należy dopuszczać, aby każdy członek zespołu pisał przy wykorzystaniu innego framework-u. Gdy dostajemy testy "w spadku" wykonane w innym narzędziu to zamiast je przepisywać, lepiej je uruchamiać razem.&lt;/p&gt;  &lt;p&gt;Dlatego w którymś z dalszych odcinków będę chciał się zmierzyć z uruchamianiem testów pod kilka platform za jednym przyciśnięciem klawisza. Ciekawe czy TestDriven.NET to potrafi ? Przyznam się że nie wiem.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Na pierwszym obrazku, czyli "Test Current Solution" jest błąd. Czy znajdzie się osoba, która uważnie przeczytała poprzedni odcinek i będzie potrafiła go poprawić ?&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1559" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/rod/archive/tags/Narz_1901_dzia/default.aspx">Narzędzia</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/MSBuild/default.aspx">MSBuild</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/TDD/default.aspx">TDD</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Automatyzacja projektu z MSBuild-em - 4. TDD</title><link>http://zine.net.pl/blogs/rod/archive/2008/07/17/automatyzacja-projektu-z-msbuild-em-4-tdd.aspx</link><pubDate>Wed, 16 Jul 2008 23:04:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1546</guid><dc:creator>rod</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;W tym odcinku zajmiemy się testowaniem.&lt;/p&gt;  &lt;h3&gt;Rozdzielna budowa&lt;/h3&gt;  &lt;p&gt;Na początek warto stworzyć dwa pomocnicze targety: "BuildApp" oraz "BuildTest". Pierwszy z nich będzie oczywiście budował projekty składające się na aplikację, a drugi testy. Do tego potrzebujemy listy projektów z rozbiciem na dwa typy. To zrobi dla nas target "GetProjectsFromSolution", który umieszczamy w Default.proj&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="GetProjectsFromSolution"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Get all the projects associated with the solution --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GetSolutionProjects&lt;/span&gt; &lt;span class="attr"&gt;Solution&lt;/span&gt;&lt;span class="kwrd"&gt;="$(SolutionPath)"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="Output"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="SolutionProjects"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GetSolutionProjects&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Filter out solution folders and non .csproj items --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt; &lt;span class="attr"&gt;Input&lt;/span&gt;&lt;span class="kwrd"&gt;="@(SolutionProjects)"&lt;/span&gt; &lt;span class="attr"&gt;Expression&lt;/span&gt;&lt;span class="kwrd"&gt;=".[\.]csproj$"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="Output"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="Projects"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Resolve test projects --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt; &lt;span class="attr"&gt;Input&lt;/span&gt;&lt;span class="kwrd"&gt;="@(Projects)"&lt;/span&gt; &lt;span class="attr"&gt;Expression&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TestDetectionExpression)[\.]csproj$"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="Output"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="TestProjects"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Resolve the libraries code projects --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AppProjects&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;="@(Projects)"&lt;/span&gt; &lt;span class="attr"&gt;Exclude&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestProjects)"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Message&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="$(NEW_LINE)Resolved the following solution projects:"&lt;/span&gt; &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;="high"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Message&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;="&lt;span class="attr"&gt;AppProjects:&lt;/span&gt;$(&lt;span class="attr"&gt;NEW_LINE&lt;/span&gt;)$(&lt;span class="attr"&gt;TAB&lt;/span&gt;)@(App&lt;span class="attr"&gt;Projects-&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;'%(RelativeDir)%(FileName)%(Extension)', '$(NEW_LINE)$(TAB)')" Importance="high"&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Message&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;="&lt;span class="attr"&gt;TestProjects:&lt;/span&gt;$(&lt;span class="attr"&gt;NEW_LINE&lt;/span&gt;)$(&lt;span class="attr"&gt;TAB&lt;/span&gt;)@(&lt;span class="attr"&gt;TestProjects-&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;'%(RelativeDir)%(FileName)%(Extension)', '$(NEW_LINE)$(TAB)')" Importance="high"&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Pomocnicze property, które później też wykorzystamy znajduje się w Settings.proj&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TestDetectionExpression&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;.[\.](Test[s]{0,1})&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TestDetectionExpression&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Jak łatwo się domyśleć jego wykonanie będzie skutkować takim wynikiem&lt;/p&gt;

&lt;div class="console-wrapper"&gt;
  &lt;div class="console"&gt;
    &lt;pre class="alt"&gt;C:\...\trunk&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&lt;/span&gt;msbuild Default.proj /t:GetProjectsFromSolution&lt;/pre&gt;

    &lt;pre class="alteven"&gt;...&lt;/pre&gt;

    &lt;pre class="alt"&gt;Resolved the following solution projects:&lt;/pre&gt;

    &lt;pre class="alteven"&gt;AppProjects:&lt;/pre&gt;

    &lt;pre class="alt"&gt;      C:\...\trunk\src\app\MyProject\MyProject.csproj&lt;/pre&gt;

    &lt;pre class="alteven"&gt;TestProjects:&lt;/pre&gt;

    &lt;pre class="alt"&gt;      C:\...\trunk\src\test\MyProject.Tests\MyProject.Tests.csproj&lt;/pre&gt;

    &lt;pre class="alteven"&gt;...&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Parę słów wyjaśnienia. Zwróćcie uwagę, że lista projektów jest pobierana z solution, z property "SolutionPath". Jeżeli nasza aplikacja składa sie z wielu projektów, może się okazać, że warto zrobić dodatkowe pliki .sln grupujące projekty w zależności np. od warstwy - MySolution.Services.sln. Teraz, aby zbudować kod z tej okrojonej grupy wystarczy ...&lt;/p&gt;

&lt;div class="console-wrapper"&gt;
  &lt;pre class="console"&gt;C:\...\trunk&amp;gt; msbuild Default.proj /t:BuildApp /p:SolutionPath=.\MySolution.Services.sln&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Jak widać do rozdzielenia różnych rodzajów projektów wykorzystujemy expression regexp-a. Należy również zwrócić uwagę na "ItemGroup". Od wersji MSBuild 3.5 można używać "ItemGroup" jak i "PropertyGroup" wewnątrz znaczników "Target". W poprzedniej wersji&amp;nbsp; należało wykorzystywać "CreateItem" i "CreateProperty". Dodatkowo możemy teraz usuwać wartości z ItemGroup np. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;—Remove *.licx from the EmbeddedResource list - -&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EmbeddedResource&lt;/span&gt; &lt;span class="attr"&gt;Remove&lt;/span&gt;&lt;span class="kwrd"&gt;="*.licx"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Aby zwiększyć czytelność dodałem pomocnicze properties takie jak $(NEW_LINE) i $(TAB). Są one zadeklarowane w pliku Settings.proj w następujący sposób...&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;&amp;lt;!-- ASCII Constants --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NEW_LINE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;%0D%0A&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;NEW_LINE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TAB&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;%09&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TAB&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DOUBLE_QUOTES&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;%22&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DOUBLE_QUOTES&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SPACE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;%20&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SPACE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;PropertyGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Teraz pozostaje nam zbudować brakujące zadania "BuildApp" i "BuildTest" oraz zrefaktorować target "BuildAll", który powstał w poprzednim odcinku.&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildAll"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildApp;BuildTest"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildApp"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="GetProjectsFromSolution"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="@(AppProjects)"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;             &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="Build"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="TargetOutputs"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="AppAssemblies"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Add all assemblies to all build assemblies --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;BuildAssemblies&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;="@(AppAssemblies)"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildTest"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="GetProjectsFromSolution"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestProjects)"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;             &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="Build"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="TargetOutputs"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAssemblies"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Add all assemblies to all build assemblies --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;BuildAssemblies&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestAssemblies)"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Wynikiem zadań są properties "AppAssemblies", "TestAssemblies" oraz "BuildAssemblies", które zawierają odpowiednio pliki wynikowe aplikacji, testów oraz wszystkie pliki, które powstały w trakcie tego przebiegu budowy.&lt;/p&gt;

&lt;h3&gt;Uruchomienie testów&lt;/h3&gt;

&lt;p&gt;Do testów wykorzystałem NUnit v2.5 alpha. Znajduje się on w tools\nunit. Napisałem prostą klasę testująca, która zwraca jeden poprawny i jeden niepoprawny rezultat. Naszym celem jest teraz umożliwienie uruchomienia testu dla pojedynczego projektu jak i zbiorowo czyli ...&lt;/p&gt;

&lt;div class="console-wrapper"&gt;
  &lt;div class="console"&gt;
    &lt;pre class="alt"&gt;C:\...\trunk&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; msbuild src\test\MyProject.Tests\MyProject.Tests.csproj /t:Test&lt;/pre&gt;

    &lt;pre class="alteven"&gt;C:\...\trunk&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; msbuild Default.proj /t:TestAll&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Zaczynamy od definicji ścieżki do NUnit w pliku Settings.proj&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NUnitPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;$(ToolsPath)\nunit&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;NUnitPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Następnie tworzymy target "Test" w Common.Targets&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Test"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="Build"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assemblies&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TargetDir)\$(TargetName).dll"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt; &lt;span class="attr"&gt;Input&lt;/span&gt;&lt;span class="kwrd"&gt;="@(Assemblies)"&lt;/span&gt; &lt;span class="attr"&gt;Expression&lt;/span&gt;&lt;span class="kwrd"&gt;="&lt;/span&gt;&lt;span class="kwrd"&gt;$(TestDetectionExpression)&lt;/span&gt;&lt;span class="kwrd"&gt;[\.]dll$"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="Output"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAssemblies"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NUnit&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '@(TestAssemblies)' != '' "&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="attr"&gt;ToolPath&lt;/span&gt;&lt;span class="kwrd"&gt;="$(NUnitPath)"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="attr"&gt;Assemblies&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestAssemblies)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Tutaj zastosowałem małą sztuczkę w celu wyodrębnienia testów należących do faktycznie kompilowanego projektu. Może zdarzyć się sytuacja, że jeden test zależy od drugiego testu i oba assemblies o końcówce *.Test.dll razem znajda się w $(TargetDir), a nam zależy aby testować tylko jedno, aktualnie zbudowane assembly. Jeżeli nie ma plików testowych, wówczas NUnit nie jest uruchamiany.&lt;/p&gt;

&lt;p&gt;"TestAll" w Default.proj możemy zaprojektować na dwa sposoby&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAll"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="GetProjectsFromSolution"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestProjects)"&lt;/span&gt; &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="Test"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Czyli wywołanie zadania "Test" dla każdego projektu testowego, co skutkuje również jego budową lub ...&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAll"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildTest"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NUnit&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '@(TestAssemblies)' != '' "&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="attr"&gt;ToolPath&lt;/span&gt;&lt;span class="kwrd"&gt;="$(NUnitPath)"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="attr"&gt;Assemblies&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestAssemblies)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Pierwsze rozwiązanie wydaje się być bardziej eleganckie, zwłaszcza że drugie rozwiązanie wygląda podobnie jak w Commons.Target, wiec jak coś się zmieni w sposobie uruchamiania testu np. generowanie raportu, wówczas mamy wyraźne złamanie DRY principle i musimy poprawić kod w dwóch miejscach. Ale ... Jeżeli mamy więcej projektów testowych to przy pierwszym rozwiązaniu wykonanie będzie następujące: &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Build ProjectOne &lt;/li&gt;

  &lt;li&gt;Test ProjectOne &lt;/li&gt;

  &lt;li&gt;Build ProjectTwo &lt;/li&gt;

  &lt;li&gt;Test ProjectTwo &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;W drugim rozwiązaniu:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Build ProjectOne &lt;/li&gt;

  &lt;li&gt;Build ProjectTwo &lt;/li&gt;

  &lt;li&gt;Test ProjectOne &lt;/li&gt;

  &lt;li&gt;Test ProjectTwo &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Osobiście wole kiedy najpierw zbudują mi się wszystkie testy i jak to przebiegnie pomyślnie wówczas je przetestuje. Jednak żeby nikt nam nie zarzucał "Don't Repeat Yourself" zrobimy mały refaktoring i dodamy do pliku "Settings.proj"...&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="InternalNUnit"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NUnit&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '@(TestAssemblies)' != '' "&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="attr"&gt;ToolPath&lt;/span&gt;&lt;span class="kwrd"&gt;="$(NUnitPath)"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;        &lt;span class="attr"&gt;Assemblies&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestAssemblies)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Refaktoring Default.proj&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAll"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildTest"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CallTarget&lt;/span&gt; &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="InternalNUnit"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Refaktoring Common.Targets&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Test"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="Build;GetTestAssemblies"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CallTarget&lt;/span&gt; &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="InternalNUnit"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="GetTestAssemblies"&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="Build"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assemblies&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TargetDir)$(TargetName)*.dll"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt; &lt;span class="attr"&gt;Input&lt;/span&gt;&lt;span class="kwrd"&gt;="@(Assemblies)"&lt;/span&gt; &lt;span class="attr"&gt;Expression&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TestDetectionExpression)[\.]dll$"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Output&lt;/span&gt; &lt;span class="attr"&gt;TaskParameter&lt;/span&gt;&lt;span class="kwrd"&gt;="Output"&lt;/span&gt; &lt;span class="attr"&gt;ItemName&lt;/span&gt;&lt;span class="kwrd"&gt;="TestAssemblies"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegexMatch&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Uwaga: &lt;/strong&gt;Target "Test" umyślnie rozbiłem na dwa targety. MSBuild ma takie ograniczenie, że jeżeli manipulujemy jakimś Item lub Property to zmiana ta będzie widoczna dla innych targetów dopiero po zakończeniu aktualnego. Zatem manipulacja Property a potem wywołanie CallTarget nie powiodłaby się. Na to trzeba uważać.&lt;/p&gt;

&lt;p&gt;Kod do dzisiejszego odcinka znajdziecie tutaj -&amp;gt; &lt;a href="http://rodsamples.googlecode.com/svn/MSBuildTutorial/tags/part004"&gt;Part004&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W następnym odcinku zobaczymy jak zrobić Assembly.cs, którego nikt nie będzie widział w projekcie, czyli dynamiczne dokładanie plików.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1546" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/rod/archive/tags/Narz_1901_dzia/default.aspx">Narzędzia</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/MSBuild/default.aspx">MSBuild</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/NUnit/default.aspx">NUnit</category><category domain="http://zine.net.pl/blogs/rod/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Transakcyjny mailing</title><link>http://zine.net.pl/blogs/jakubin/archive/2008/07/16/transakcyjny-mailing.aspx</link><pubDate>Tue, 15 Jul 2008 22:39:58 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1524</guid><dc:creator>jakubin</dc:creator><slash:comments>6</slash:comments><description>W czym problem? Wysłanie wiadomości e-mail w .NET jest dziecinnie proste: MailMessage message = new MailMessage( &amp;quot;from@server.com&amp;quot; , &amp;quot;to@server.com&amp;quot; , &amp;quot;Temat&amp;quot; , &amp;quot;Treść&amp;quot; ); SmtpClient smtp = new SmtpClient(); smtp.Send(message); Powyższy przykład jest bardzo kr&amp;#243;tki, choć i tak został napisany niezwykle rozwlekle - wersja zminimalizowana zajęłaby 1 linijkę (w obu przypadkach ustawienia serwera pocztowego znajdują się w pliku konfiguracyjnym). Właściwie ten...(&lt;a href="http://zine.net.pl/blogs/jakubin/archive/2008/07/16/transakcyjny-mailing.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1524" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/jakubin/archive/tags/transakcje/default.aspx">transakcje</category></item><item><title>Wstęp do Visual Programming Language</title><link>http://zine.net.pl/blogs/marcel/archive/2008/07/15/wst-p-do-visual-programming-language.aspx</link><pubDate>Tue, 15 Jul 2008 21:55:39 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1521</guid><dc:creator>Marcin Celej</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;Jednym z element&amp;#243;w &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=EB00C558-2163-45A5-BEFE-531AD48BC525&amp;amp;displaylang=en"&gt;Microsoft Robotics Studio&lt;/a&gt; jest &lt;a href="http://msdn.microsoft.com/pl-pl/library/bb483088(en-us).aspx"&gt;Visual Programming Language&lt;/a&gt;. W skład MRS wchodzą jeszcze superciekawe &lt;a href="http://msdn.microsoft.com/pl-pl/library/bb905448(en-us).aspx"&gt;Decentralized Software Services&lt;/a&gt; oraz &lt;a href="http://msdn.microsoft.com/pl-pl/library/bb905447(en-us).aspx"&gt;Concurrency and Coordination Runtime&lt;/a&gt;. Jendakże o tych mechanizmach napiszę innym razem.&lt;/p&gt;  &lt;p&gt;Jeśli chodzi o VPL to zainteresował mnie on w kontekście koncepcji wizualizacji algorytm&amp;#243;w - czyli jak oddać programowanie w ręce 'normalnego' człowieka. &lt;/p&gt;  &lt;p&gt;Aby szybko zobaczyć w jaki spos&amp;#243;b można używać VPL obejrzyjcie screen-cast, kt&amp;#243;ry nagrałem: &lt;a title="http://vimeo.com/1313420" href="http://vimeo.com/1313420"&gt;http://vimeo.com/1313420&lt;/a&gt;     &lt;br /&gt;Nagranie jest nieme przerwane jedynie głosem robota :). Jest r&amp;#243;wnież kr&amp;#243;tkie - 4 minuty więc można obejrzeć w trakcie oczekiwania na skompilowanie się aplikacji :).&lt;/p&gt;  &lt;p&gt;Poniżej ekranik z jednego z algorytm&amp;#243;w, na kt&amp;#243;rych to testowałem wraz z opisem co w kt&amp;#243;rej akcji się dzieje: &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="541" alt="vpl-increment-and-say" src="http://zine.net.pl/blogs/marcel/WindowsLiveWriter/WstpdoVisualProgrammingLanguage_1488A/vpl-increment-and-say_3.png" width="712" align="left" border="0" /&gt;&lt;/td&gt;        &lt;td&gt;         &lt;ol&gt;           &lt;li&gt;Stała typu int r&amp;#243;wna 2&lt;/li&gt;            &lt;li&gt;Okienko z pytaniem o podanie początkowej wartości zmiennej używanej w pętli&lt;/li&gt;            &lt;li&gt;Rzutowanie rezultatu zgromadzonego w okienku na int&lt;/li&gt;            &lt;li&gt;Podstawienie zmiennej używanej w pętli&lt;/li&gt;            &lt;li&gt;Wyliczenie tekstu do wym&amp;#243;wienia (rzutowanie zmiennej na string)&lt;/li&gt;            &lt;li&gt;Akcja m&amp;#243;wiąca wartośc zmiennej (odlicza liczby)&lt;/li&gt;            &lt;li&gt;Warunek if kończący pętlę&lt;/li&gt;            &lt;li&gt;Wyrażenie zwiększające wartość zmiennej o 1&lt;/li&gt;            &lt;li&gt;Podstawienie wyliczonej wartości do zmiennej&lt;/li&gt;            &lt;li&gt;Połączenie przepływ&amp;#243;w - akcja merge działa w ten spos&amp;#243;b, że to co w nią wchodzi w tym samym momencie wychodzi&lt;/li&gt;         &lt;/ol&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;Miłej zabawy z VPL.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1521" width="1" height="1"&gt;</description></item><item><title>[PL] Chcę oglądać Twoje logi</title><link>http://zine.net.pl/blogs/sqlgeek/archive/2008/07/15/pl-chc-ogl-da-twoje-logi.aspx</link><pubDate>Tue, 15 Jul 2008 19:10:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1513</guid><dc:creator>brejk</dc:creator><slash:comments>5</slash:comments><description>&lt;P&gt;Temat zmniejszania rozmiaru pliku dziennika transakcji bazy i wszelkich katastrof z tym procesem związanych wraca na forum mojego ulubionego portalu - &lt;A href="http://wss.pl/frmGroups.aspx"&gt;WSS.pl&lt;/A&gt; - jak bumerang. Jedną z metod zmniejszania loga wykorzystywanych namiętnie i bez opamiętania przez użytkowników jest metoda “brute force” – czyli metoda oparta o usunięcie pliku loga i podłączenie tylko pliku danych do instancji SQL Server przy użyciu procedury systemowej &lt;STRONG&gt;sp_attach_single_file_db&lt;/STRONG&gt;. Czasem działa…&lt;/P&gt;
&lt;H3&gt;Upadek mitu&lt;/H3&gt;
&lt;P&gt;Do czasu… Niekiedy może skończyć się katastrofą zwizualizowaną na przykład takim komunikatem błędu:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;File activation failure. The physical file name "C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Test_log.ldf" may be incorrect. &lt;BR&gt;The log cannot be rebuilt because the database was not cleanly shut down. &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#ff0000&gt;Msg 1813, Level 16, State 2, Line 1 &lt;BR&gt;Could not open new database 'test'. CREATE DATABASE is aborted.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Tak najczęściej weryfikuje się mity – na własnej skórze. Niestety.&lt;/P&gt;
&lt;H3&gt;Co, jak już się dałem złapać na mit?&lt;/H3&gt;
&lt;P&gt;Czyli jednak to niekoniecznie jest dobra metoda… Ok, ale co, jeśli już log został usunięty i nie ma szybkiej (lub wręcz żadnej) możliwości przywrócenia go?&lt;/P&gt;
&lt;P&gt;Wtedy trzeba wykonać następujące kroki:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Stworzyć bazę o nazwie identycznej z nazwą świeżo “zepsutej” bazy, lokalizując pliki w innym katalogu niż pliki bazy “zepsutej” (żeby nie trzeba było kopiować “osieroconego” pliku .mdf bazy, której log nieszczęśliwie skasowaliśmy). Najlepiej od razu ograniczyć dostęp do nowej bazy dla jednego użytkownika. W SSMS można to ustawić podczas tworzenia bazy danych w zakładce Options okna New Database. Można też wykonać polecenie ALTER DATABASE:&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ALTER&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DATABASE&lt;/span&gt; Test &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; SINGLE_USER &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;WITH&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ROLLBACK&lt;/span&gt; IMMEDIATE&lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;
&lt;LI&gt;Przenieść bazę w tryb OFFLINE: &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ALTER&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DATABASE&lt;/span&gt; Test &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; OFFLINE &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;WITH&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ROLLBACK&lt;/span&gt; IMMEDIATE&lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI&gt;Podmienić plik .mdf bazy na plik bazy “zepsutej”. 
&lt;LI&gt;Przenieść bazę w tryb ONLINE:&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ALTER&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DATABASE&lt;/span&gt; Test &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; ONLINE&lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;
&lt;LI&gt;Przenieść bazę w tryb EMERGENCY: &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ALTER&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DATABASE&lt;/span&gt; Test &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; EMERGENCY&lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;BR&gt;Przy tej okazji zapewne SQL Server uraczy nas komunikatami błędów w stylu: &lt;BR&gt;&lt;FONT color=#ff0000&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;Msg 5173, Level 16, State 1, Line 1 &lt;BR&gt;One or more files do not match the primary file of the database. If you are attempting to attach a database, retry the operation with the correct files.&amp;nbsp; If this is an existing database, the file may be corrupted and should be restored from a backup. &lt;/FONT&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;Log file 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Test_log.ldf' does not match the primary file.&amp;nbsp; It may be from a different database or the log may have been rebuilt previously. &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#ff0000&gt;Msg 945, Level 14, State 2, Line 1 &lt;BR&gt;Database 'Test' cannot be opened due to inaccessible files or insufficient memory or disk space.&amp;nbsp; See the SQL Server errorlog for details. &lt;BR&gt;Msg 5069, Level 16, State 1, Line 1 &lt;BR&gt;ALTER DATABASE statement failed. &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;
&lt;LI&gt;Wykonać polecenie DBCC CHECKDB (tu czas trwania i komunikaty zwracane przez SQL Server mogą być różne, ale koniec końców baza powinna być w statusie SINGLE_USER):&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DBCC&lt;/span&gt; CHECKDB(Test, REPAIR_ALLOW_DATA_LOSS)&lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;
&lt;LI&gt;Przywrócić dostęp do bazy użytkownikom:&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ALTER&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;DATABASE&lt;/span&gt; Test &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; MULTI_USER&lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Po całym tym procesie należy też wykonać oczywiście pełny backup bazy.&lt;/P&gt;
&lt;H3&gt;Wnioski i sugestie&lt;/H3&gt;
&lt;P&gt;Z podobnych historii płyną liczne wnioski:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Metoda na zmniejszenie pliku dziennika transakcji bazy polegająca na usuwaniu tegoż pliku jest niebezpieczna i zdecydowanie niezalecana.&lt;/FONT&gt;&lt;/STRONG&gt; Mówiąc po mojemu – za takie rzeczy ucinamy rączki :-) 
&lt;LI&gt;Tą i podobne metody pokazują i czasem polecają (sic!) szczęśliwi ludzie, którzy powinni chyba częściej grywać w totka. Niestety, ponoć także niektórzy MCT należą do tych farciarzy i uczą swoich kursantów takich metod na szkoleniach. A zatem… 
&lt;LI&gt;Nawet, jak coś bierzemy za pewnik, “bo tak powiedział jeden trener”, weryfikujmy zasłyszane “dobrze znane prawdy” empirycznie. Unikniemy rozczarowań i przykrych niespodzianek w najmniej oczekiwanych momentach. 
&lt;LI&gt;Do ewentualnego zmniejszania pliku dziennika transakcji używamy zestawu – &lt;STRONG&gt;backup dziennika transakcji + DBCC SHRINKFILE&lt;/STRONG&gt;. A tak w ogóle, nim zmniejszysz plik loga, zadaj sobie pytanie, po co właściwie chcesz to zrobić? :-) 
&lt;LI&gt;Przy bazie danych działającej w trybie FULL (recovery mode) &lt;STRONG&gt;niezbędna jest odpowiednia strategia backupowania loga&lt;/STRONG&gt; (inaczej – trzeba go backupować, jeśli nie chcemy mieć problemów – narastającego wiecznie pliku logów czy długiego czasu podnoszenia bazy po restarcie serwera). &lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Inni mówią i piszą o logu&lt;/H3&gt;
&lt;P&gt;Bardzo interesująco o logu opowiadali swego czasu na konferencji Microsoft Technology Summit 2006 Marcin Szeliga i Maciej Pilecki (“&lt;A href="http://www.microsoft.com/poland/technet/mts/pa112.mspx"&gt;Strojenie SQL Server 2005&lt;/A&gt;”). O złym nawyku usuwania loga wspomniał też wymieniony Maciej Pilecki w swojej sesji o mitach na konferencji Communities to Communities 2008 (“&lt;A href="http://ftp.itcore.pl/C2C/SQL/SQL05_Pilecki_Myths_2.wmv"&gt;Największe mity na temat SQL Server&lt;/A&gt;”). Bardzo dobry artykuł o zasadach funkcjonowania dziennika transakcji i metodach utrzymania go napisał dla Technet Polska &lt;A href="http://strefa.guzowski.info"&gt;Marcin Guzowski&lt;/A&gt; (“&lt;A href="http://www.microsoft.com/poland/technet/article/art0091_01.mspx"&gt;Log transakcyjny w SQL Server 2005&lt;/A&gt;”). Firma Microsoft w swoich artykułach także opisuje, jak radzić sobie z rosnącymi plikami dziennika transakcji (&lt;A href="http://support.microsoft.com/kb/873235"&gt;KB873235&lt;/A&gt;, &lt;A href="http://support.microsoft.com/kb/272318"&gt;KB272318&lt;/A&gt;).&lt;/P&gt;
&lt;H3&gt;Suma sumarum&lt;/H3&gt;
&lt;P&gt;Na zakończenie chciałbym zaznaczyć, że opisana metoda ratowania się z opresji po usunięciu pliku dziennika transakcji nie jest wynikiem moich własnych przeżyć. Po prostu przeprowadziłem w ramach testów małą symulację i okazało się, że opisana wyżej procedura pozwoliła mi przywrócić bazę danych online. Ze swojej strony nie gwarantuję, że procedura ta pomoże każdemu. Ale – z drugiej strony - po przeczytaniu niniejszej notki, powinieneś już wiedzieć, jak uniknąć podobnych sytuacji.&lt;/P&gt;
&lt;P&gt;Mam nadzieję, że opisany problem w przyszłości będzie pojawiał się coraz rzadziej i ludzie zaczną jednak stosować najlepsze praktyki w odniesieniu do dziennika transakcji. I nie będzie nam już dane urządzać konkursu pt. “Kto ma największego loga?”… :-)&lt;/P&gt;
&lt;P&gt;I jeszcze jedno. Tytuł notki to oczywiście parafraza tytułu znanej piosenki znanego zespołu Czarno-Czarni ;-) Zasugerował mi go &lt;A href="http://zine.net.pl/blogs/mad"&gt;Marek Adamczuk&lt;/A&gt;. Szczypta ironii