środa, 23 grudnia 2009

Jak zmieniać wartość ColumnSpan w kontrolce GridView

Potrzebowałem przerobić grida tak aby wyświetlał co drugi wiersz z inną ilością kolumn.

Na początek podpinamy się dometody GridView1_RowDataBound

Jeśli kolumna z której pobieramy wartości jest visible to nie ma problemu, dane pobieramy przez:


int index = int.Parse(e.Row.Cells[GridView1.Columns.Count - 1].Text);





Niestety, jeżeli kolumna jest ustawiona jako unvisible musimy kod zmienić na:


int index = int.Parse(((System.Data.DataRowView)e.Row.DataItem).Row.ItemArray.GetValue(67).ToString());





Następnie łatwo ustawiamy ColumnSpan


e.Row.Cells[2].ColumnSpan = 4;





A tutaj widać wynik jaki udało się osiągnąć:



wtorek, 22 grudnia 2009

Linq - notatki

Mam podciągnięta listę obiektów zdefuniowanego typu które posiadają min takie właściwości:


        [SqlHelper.DynamicBinding()]


        public string DealerName { get; set; }


 


        [SqlHelper.DynamicBinding()]


        public Guid DealerId { get; set; }





Chciałem je pogrupować w linq , tak więc wyszedł mały kawałek kodu.





            _list = SurveyReportRecordDA.Get();


 


            var result = from o in _list


                         group o by new { o.DealerId, o.DealerName } into g


                         select new { g.Key.DealerId, g.Key.DealerName};




Przykład trywialny, ale widać jak składać zapytanie grupowania.




kolejny przykład to prosty select na liście przy uzyciu Linq, a następnie wrzucenie wyniku do Listy


                var query = from o in _dataForReport


                            where o.DealerId == _dealerList[i].DealerId


                            select o;


 


                List<SurveyReportRecord> _dealerRecord = query.ToList<SurveyReportRecord>();


czwartek, 17 grudnia 2009

ASSEMBLY MS SQL 2005 - notatki

Będe zamieszczał w tym poście notatki z moich prac związanych z ASSEMBLY na MS SQL 2005



--Włączanie obsługi assembly na serwerze ms sql
use master
go
sp_configure 'clr enabled', 1
go
reconfigure
go



--sprawdzanie konfiguracji
sp_configure 'clr enabled'


--ładowanie assembly
USE ASM --This is our test database.
GO
CREATE ASSEMBLY [test_call] FROM 'C:\work\ASM - CP\TEST\TEST\bin\Debug\test.dll'



bledy:

en:
The requested operation requires a Sql Server execution thread. The current thread was started by user code or other non-Sql Server engine code.
pl:
Żądana operacja wymaga kontekstu SqlClr, który jest dostępny tylko podczas uruchamiania procesu programu SQL Server.

solution:
http://www.sqlclr.net/Articles/tabid/54/articleType/ArticleView/articleId/34/Default.aspx




Metoda do instalowanie Assembly na serwerze

///
///
///

///
/// sciezka gdzie znajduje sie biblioteka
/// nazwa pod jaka ma zostac utworzone assmebly w bazie
/// Nazwa klasy dla danej assmbly
/// pelna nazwa biblioteki np test.dll
/// nazwa bazy na jakiej ma zostac postawiona assembly
public static void InstallMe(string connectionString, string path, string assemblyName, string className, string assemblyDLL
, string databaseName)
{
try
{
string directory = Path.GetDirectoryName(path);


string sql = @"USE {0} ";

//skasowanie procedur(y) uzywjacych assembly
sql += "IF EXISTS ( select 1 from sysobjects WHERE xtype = 'PC' AND name = '{1}') BEGIN ";
sql += "DROP PROCEDURE {1} END ";

//skasowanie assembly
sql += "IF EXISTS (SELECT 1 FROM [sys].[assemblies] AS asmbl WHERE asmbl.[name] = '{1}') BEGIN ";
sql += "DROP ASSEMBLY {1} END ";

//dodaje assembly
sql += "CREATE ASSEMBLY [{1}] FROM '{2}{3}' ";



string sqlM1 = "CREATE PROCEDURE asm_AssemblyCCPForMSSQL ";
sqlM1 += "@ConnectionString [nvarchar](100), ";
sqlM1 += "@XMLFileLocation[nvarchar](100) ";
sqlM1 += "WITH EXECUTE AS CALLER ";
sqlM1 += "AS ";
sqlM1 += "EXTERNAL NAME [{1}].[{4}].[ImportXMLToDB] ";





sql = string.Format(sql, databaseName, assemblyName, path, assemblyDLL, className);
sqlM1 = string.Format(sqlM1, databaseName, assemblyName, path, assemblyDLL, className);


//zapis sql do pliku
FileStream file = File.Create(path + "create_script.sql");
file.Close();
System.IO.StreamWriter sw = new StreamWriter(path + "create_script.sql", true);
sw.WriteLine(sql);
sw.WriteLine("/*################################*/");
sw.WriteLine(sqlM1);
sw.Close();




using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand InsertCurrencyCommand = new SqlCommand();
InsertCurrencyCommand.CommandText = sql;
InsertCurrencyCommand.Connection = conn;

SqlCommand InsertCurrencyCommand2 = new SqlCommand();
InsertCurrencyCommand2.CommandText = sqlM1;
InsertCurrencyCommand2.Connection = conn;

conn.Open();
InsertCurrencyCommand.ExecuteNonQuery();
InsertCurrencyCommand2.ExecuteNonQuery();
conn.Close();
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}


}


Oraz jej przykładowe wywołanie:

MSSQLASM.InstallMe("Data Source=APE\\SQLEXPRESS;Initial Catalog=ASM;Integrated Security=True"
, "C:\\work\\ASM - CP\\Assembly_CPP_C+\\Assembly_CPP_C+\\AssemblyCCP\\AssemblyCCPForMSSQL\\bin\\Debug\\"
, "asm_AssemblyCCPForMSSQL"
, "AssemblyCCPForMSSQL"
, "AssemblyCCPForMSSQL.dll"
, "ASM");

Ładowanie excela przez OleDbConnection

Jak go podłączyć ? Poniżej prezentuje jak podpiąć sięprzy użyciu silnika do pliku i załadować jego arkusz do tabeli, oczywiście mapując nazwy kolumn.

Należy pamiętać o using System.Data.OleDb;

string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + src + @";Persist Security Info=False;Extended Properties=""Excel 12.0;HDR=YES;""";


OleDbConnection excelConnection = new OleDbConnection(connectionString);


excelConnection.Open();


 


DataTable dt = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);


List<string> excelSheets = new List<string>(dt.Rows.Count);


 


int i = 0;


foreach (DataRow row in dt.Rows)


{


    string strSheetTableName = row["TABLE_NAME"].ToString();


    excelSheets.Add(strSheetTableName.Substring(0, strSheetTableName.Length - 1));


    i++;


}


 


string strSQL = "SELECT * FROM [" + excelSheets[excelSheets.Count - 1] + "$]";


OleDbCommand dbCommand = new OleDbCommand(strSQL, excelConnection);


OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand);


DataTable dTable = new DataTable();


dataAdapter.Fill(dTable);


 


dTable.Dispose();


dataAdapter.Dispose();


dbCommand.Dispose();


excelConnection.Close();


excelConnection.Dispose();


 


 


for (int c = 0; c < dTable.Columns.Count; c++)


{


    dTable.Columns[c].ColumnName = GetColumnNameWithoutSpecialCharacters(dTable.Columns[c].ColumnName);


}









Użyłem tutaj metody GetColumnNameWithoutSpecialCharacters, bo kasuje wszystkie polskie znaczki , to ułatwia później prace na obiektach na które mapuje rekordy.

string GetColumnNameWithoutSpecialCharacters(string col)
{
col = col.ToUpper();
col = col.Replace("Ę", "E");
col = col.Replace("Ó", "O");
col = col.Replace("Ą", "A");
col = col.Replace("Ś", "S");
col = col.Replace("Ł", "L");
col = col.Replace("Ż", "Z");
col = col.Replace("Ź", "Z");
col = col.Replace("Ń", "M");
col = col.Replace("Ć", "C");
return col;
}

Finito!

Parsowanie rekordów Excel'a na zdefiniowane obiekty

Spędziłem ostatnio troche czasu nad importem plików excela. Mozolna praca, zwłaszcza kiedy należy jeszcze przeanalizować zawartość wierszy w kodzie.

Postanowiłem troche uprościć życie, napisałem kilka lini kodu, które automatycznie parsują wiersze excela na obiekty wczesniej przez nas zdefiniowane.

Na poczatke zobaczmy jak budujemy obiekt do reprezentacji wiersza:

Bo stworzeniu klasy dodajemy do niej tyle właściwości ile mamy kolumn do zmapowania z excela i tak dla przykładu:

[MuchSoft.BLL.SqlHelper.DynamicBindingExcelColumn("imie klienta")]
public string ImieKlienta { get; set; }

Definicja atrybutu ktorego uzylem znajduje sie tutaj:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class DynamicBindingExcelColumnAttribute : System.Attribute
{
public string column_name { get; set; }
public bool required_field { get; set; }


public DynamicBindingExcelColumnAttribute()
{
}

public DynamicBindingExcelColumnAttribute(string columnName)
{
column_name = columnName;
required_field = true;
}

public DynamicBindingExcelColumnAttribute(string columnName, bool required)
{
column_name = columnName;
required_field = required;

}
}


Jako parametr atrybutu podajemy nazwe kolumny ktora mamy w excelu do zmapowania w tym przypadku "imie klienta"


W konstruktorze obiektu ktory utworzylismy na potrzeby mapowania rekordow odpalamy metode parsujaca:
MuchSoft.BLL.SqlHelper.DynamicBindingDataManager.BindPropertiesFromExcel(this, dr, "");

Tutaj wchodza nam trzy parametry this - reprezentuje obiekt ktory mapujemy, dr to wiersz z excela

Teraz slow kilka o samej metodzie parsujacej

Deklaracja
static public object BindPropertiesFromExcel(object o, DataRow reader, string columnList)


Podciagniecie wlasciwosci oraz zbudowanie listy kolumn
PropertyInfo[] pri = o.GetType().GetProperties();

List _columns = new List();

foreach (string s in columnList.Split(','))
{
if (s.Length > 0)
_columns.Add(s);
}


Przeglad wlasciwosci i podpiecie do nich wartosci
foreach (PropertyInfo p in pri)
{
try
{
object[] attributes = p.GetCustomAttributes(false);

if (attributes.Length > 0 && attributes.GetValue(0).GetType().Name == "DynamicBindingExcelColumnAttribute")
{
Type t = o.GetType();
PropertyInfo pi = t.GetProperty(p.Name);
DynamicBindingExcelColumnAttribute atr = (DynamicBindingExcelColumnAttribute)attributes.GetValue(0);
string columnName = atr.column_name == null ? p.Name : atr.column_name;


if ((_columns.Count > 0 && _columns.Contains(columnName)) || _columns.Count == 0)
{
if (pi.PropertyType.FullName == typeof(int).FullName)
pi.SetValue(o, int.Parse(reader[columnName].ToString()), null);
else if (pi.PropertyType.FullName == typeof(string).FullName)
pi.SetValue(o, reader[columnName].ToString().Trim(), null);
else if (pi.PropertyType.FullName == typeof(decimal).FullName)
pi.SetValue(o, decimal.Parse(reader[columnName].ToString()), null);
}
}
}
catch (Exception e)
{
return e;
}
}

return o;


I finito.

środa, 16 grudnia 2009

Troubleshooting permissions problems

Komunikat w polskiej wersji językowej:
Aparat bazy danych programu Microsoft Office Access nie może otworzyć pliku ... lub zapisać do niego. Plik jest już otwarty do wyłącznego użytku przez innego użytkownika lub potrzebne jest uprawnienie do przeglądania i zapisywania jego danych.


Ten sam komunikat w wersji angielskiej:
The Microsoft database engine cannot open the file ...
It is already opened exclusively by another
user, or you need permission to view its data.

Jak łatwo się domyśleć z wersją angielską, można odnaleźć rozwiązanie dużo szybciej niż mając tylko polską wersje błedu. Niestety posiadając polskiego windowsa na stacji roboczej dostajemy komunikaty w wersji polskiej.

Poniżej lista wskazówek czgo moze dotyczyć błąd:
http://www.xlinesoft.com/asprunnerpro/docs/error_the_microsoft_jet_database_engine_cannot%20open%20the%20file%20%28unknown%29.htm

Oraz rozwiązanie przypadku z uprawnieniami:
http://livedocs.adobe.com/dreamweaver/mx2004/using/wwhelp/wwhimpl/common/html/wwhelp.htm?context=Using_Dreamweaver&file=31_trou3.htm

piątek, 4 grudnia 2009

jak małe dziecko

jesli klamiesz, robisz to najpiekniej jak to mozliwe
kiedy mysle, mysle o Tobie
jesli jestes diablem, przybrales idealna forme
gdybym o Tobie wiedzial wczesniej, spalbym do dnia kiedy Cie poznalem
obłęd, dzika namiętność, szaleństwo, zwolnione wodze fantazji
to wszystko jest jak jeden wyraz, w opowiadaniu o Tobie
pragne Cie slyszec, widziec , dotykac
dla M.

wtorek, 1 grudnia 2009

Kiedy wazon rozsypie się na kawałki

na kawałki życia, zobaczysz czym jest życie

życie jest łzą na widok przyjaciela przed ołtarzem
odgłosem kamienia w wodzie, rzuconego przez zakochanych
jest zwykłym "cześć" od koleżanki, która kocha swojego faceta
kroplą wody, która popłynie po awari wodociągu
słowem "jeść" od nieznajomej osoby na chodniku
usmiechem matki, kiedy masz szczęście stanąć przed nią
radością Dziadka, który widzi wnuka
głosem Ojca, ucieszonego telefonem dziecka
jest myślą o szczęśliwej siostrze
telefonem od brata, który nie myśli jak Ty

o tym pomyślisz odchodząc