.comment-link {margin-left:.6em;}
Marc Boizeau's blog
Friday, November 26, 2004
  Mandelbrot in C# , the sources!
Hello everybody,
yesterday I posted a link to mandelbrot in c# on the microsoft.public.dotnet.framework.drawing usenet group . Morten Wennevik reply to me and argued that a lot of code were missing. So, today I post the complete sources. He also said that Visual studio isn't mandatory to build a .Net Windows application. He is right! So I will also give the way to compile it without Visual Studio .net, just with the framework:

Step 1 Create a directory for the project
Step 2 In this directory put a text file named fractalform.cs (personnaly I used a UTF-8 format with Notepad) containing the following:

using System;
using System.Drawing;
using System.Windows.Forms;


namespace mandelbrot
{


/// <summary>
/// Description résumée de Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
Complex C1,C2,C3;
private System.Windows.Forms.Button trace;
private System.Windows.Forms.PictureBox BoiteImage;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox hgx;
private System.Windows.Forms.TextBox hgy;
private System.Windows.Forms.TextBox bdy;
private System.Windows.Forms.TextBox bdx;
private System.Windows.Forms.Label label2;
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Requis pour la prise en charge du Concepteur Windows Forms
//
InitializeComponent();

//
// TODO : ajoutez le code du constructeur après l'appel à InitializeComponent
//
}

/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Code généré par le Concepteur Windows Form
/// <summary>
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
/// </summary>
private void InitializeComponent()
{
this.trace = new System.Windows.Forms.Button();
this.BoiteImage = new System.Windows.Forms.PictureBox();
this.hgx = new System.Windows.Forms.TextBox();
this.hgy = new System.Windows.Forms.TextBox();
this.bdy = new System.Windows.Forms.TextBox();
this.bdx = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// trace
//
this.trace.Location = new System.Drawing.Point(512, 8);
this.trace.Name = "trace";
this.trace.Size = new System.Drawing.Size(80, 32);
this.trace.TabIndex = 12;
this.trace.Text = "trace";
this.trace.Click += new System.EventHandler(this.button1_Click);
//
// BoiteImage
//
this.BoiteImage.Location = new System.Drawing.Point(24, 56);
this.BoiteImage.Name = "BoiteImage";
this.BoiteImage.Size = new System.Drawing.Size(584, 416);
this.BoiteImage.TabIndex = 13;
this.BoiteImage.TabStop = false;
//
// hgx
//
this.hgx.Location = new System.Drawing.Point(32, 24);
this.hgx.Name = "hgx";
this.hgx.Size = new System.Drawing.Size(80, 20);
this.hgx.TabIndex = 14;
this.hgx.Text = "-1,5";
//
// hgy
//
this.hgy.Location = new System.Drawing.Point(128, 24);
this.hgy.Name = "hgy";
this.hgy.Size = new System.Drawing.Size(80, 20);
this.hgy.TabIndex = 15;
this.hgy.Text = "-1,5";
//
// bdy
//
this.bdy.Location = new System.Drawing.Point(304, 24);
this.bdy.Name = "bdy";
this.bdy.Size = new System.Drawing.Size(80, 20);
this.bdy.TabIndex = 16;
this.bdy.Text = "1,5";
//
// bdx
//
this.bdx.Location = new System.Drawing.Point(216, 24);
this.bdx.Name = "bdx";
this.bdx.Size = new System.Drawing.Size(80, 20);
this.bdx.TabIndex = 17;
this.bdx.Text = "1,5";
//
// label1
//
this.label1.Location = new System.Drawing.Point(88, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(64, 23);
this.label1.TabIndex = 19;
this.label1.Text = "hautgauche";
//
// label2
//
this.label2.Location = new System.Drawing.Point(272, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(64, 16);
this.label2.TabIndex = 20;
this.label2.Text = "BasDroite";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(632, 470);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.bdx);
this.Controls.Add(this.bdy);
this.Controls.Add(this.hgy);
this.Controls.Add(this.hgx);
this.Controls.Add(this.BoiteImage);
this.Controls.Add(this.trace);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}




private void button1_Click(object sender, System.EventArgs e)
{
int nbPix=1000;
double diagDest;

int x,y;
Bitmap Imag;
Color col;
int iDiv;
Complex c= new Complex();

//define the complex plan zone
Complex cHG = new Complex(Convert.ToDouble( this.hgx.Text),Convert.ToDouble( this.hgy.Text));
Complex cBD = new Complex(Convert.ToDouble(this.bdx.Text),Convert.ToDouble(this.bdy.Text));
diagDest=Convert.ToDouble( this.hgx.Text)-Convert.ToDouble( this.bdx.Text);

//instantiate the bitmap
Imag = new Bitmap(nbPix ,nbPix);

//scan the bitmap
for(x=0;x<Imag.Size.Width;x++)
for(y=0;y<Imag.Size.Height;y++)
{
//convert the pixel coordinate into a complex number
c = new Complex(diagDest*x/nbPix,diagDest*y/nbPix)-cHG;

//calculate divergence
iDiv = c.diverg();

//choose the color of the pixel
if (iDiv >= 255)
//if it converge it's black
col = System.Drawing.Color.FromArgb(255,0,0,0);
else //if it is not it depend of the speed
col = System.Drawing.Color.FromArgb(128,iDiv,iDiv,iDiv);

//set the pixel color
Imag.SetPixel(x,y,col );
}
//draw the image
BoiteImage.SizeMode = PictureBoxSizeMode.StretchImage ;
BoiteImage.ClientSize = new Size(Imag.Size.Width, Imag.Size.Height);
BoiteImage.Image = (Image) Imag ;

}

}
}



Step 3Put a second file named cplx.cs
containing the following

using System;// to include the basic libraries

namespace mandelbrot//a namespace groups classes working together,
{
// The main class
class Complex
{
//constants
const int IMAX_ITER = 255 ;// number of iterations to estimate the divergence
const double MODUL_LIMIT = 2;//


public double x;//pretty close to c++ syntax,
//"public" indicates that the users of the class can access this property...
public double y;

//////////////////////////
//constructors

//the basic one , do nothing but is mandatory for operators overloading
public Complex()
{}

//the main constructor
public Complex(double i, double j)
{
x = i;
y = j;
}

//////////////////////////
//Operators overloading

//plus
public static Complex operator +(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)+(c2.x);
temp.y = c1.y+c2.y;
return temp;
}
//minus
public static Complex operator -(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)-(c2.x);
temp.y = c1.y-c2.y;
return temp;
}
// multiplication, a little more complicated
public static Complex operator *(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = c1.x*c2.x-c1.y*c2.y;
temp.y = c1.y*c2.x+c1.x*c2.y;
return temp;
}

/////////////////////
//methods

//Module, used to measure the complex number
public double Module()
{
double temp;
temp = System.Math.Sqrt( x*x+y*y);
return temp ;
}
//use to measure the divergence of the complex number
//the number return is use to define the color of the affix's point
public int diverg()
{
int i=0 ;
Complex c = new Complex(x,y) ;

while (i<IMAX_ITER && c.Module()<MODUL_LIMIT)
{
c = c*c+this;//yep "*" and "+" are the operator we've just overload.
i++;
}
return i;//the number of iteration is return to set the color
}
}


}




Step 4 Now open a command line window on the directory you've just create.
type the folowing:
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe /target:winexe /recurse:*.*
(You may have to replace C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\ by your computer's c# compiler path.)


That's all folks, thanks to Morten Wennevik!

Comments are welcome!
 
Wednesday, November 24, 2004
  Mandelbrot in C#
Last week I talked a lot about Oracle and SQL, Mr Gates may be jealous ;-), let’s have a look to the .Net platform. Today I’m just going to introduce C# and a few stuff of the winform namespace (connection to Oracle will come later, be patient).

First of all, I work with Visual Studio .Net. If you want to understand something to this article you need this tool.

At school I learned Object Oriented Programming with C++ and Java. C# syntax is very close to those languages. The three languages have in common “{“, inheritance, encapsulation, a lot of keywords and something like a cultural background.
At school I also made a Mandelbrot set explorer in C++ as an OOP exercise. I find myself interesting to demonstrate C# coding with those fractal objects.

To do this I will present an object oriented construction to make calculus with complex numbers and the Mandelbrot specific method . I will then show how to use the Complex class into a simple WinForm to design Mandelbrot‘s set pictures.

OK, I won’t make a mathematical demonstration about Mandelbrot’s set here.
You just have to know that it deals with complex numbers and that you can make strange and sometimes beautiful pictures with it.

The idea is that when you multiply a complex number with itself and adds another complex number, this many times; it can grows up infinitely or converge to zero.
If it converges to zero it is a part of the set, when it grows up it is not. And you can measure at what “speed” it grows up.


So, here is my complex numbers class:

using System;// to include the basic libraries

namespace WindowsApplication1//a namespace groups classes working together,
{
// The main class
class Complex
{
//constants
const int IMAX_ITER = 255 ;// number of iterations to estimate the divergence
const double MODUL_LIMIT = 2;//


public double x;//pretty close to c++ syntax,
//"public" indicates that the users of the class can access this property...
public double y;

//////////////////////////
//constructors

//the basic one , does nothing but is mandatory for operators overloading
public Complex()
{}

//the main constructor
public Complex(double i, double j)
{
x = i;
y = j;
}

//////////////////////////
//Operators overloading, we define here basic operations on complex number

//minus
public static Complex operator -(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)-(c2.x);
temp.y = c1.y-c2.y;
return temp;
}
//plus
public static Complex operator +(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)+(c2.x);
temp.y = c1.y+c2.y;
return temp;
}
// multiplication, a little more complicated
public static Complex operator *(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = c1.x*c2.x-c1.y*c2.y;
temp.y = c1.y*c2.x+c1.x*c2.y;
return temp;
}

/////////////////////
//methods

//Module, used to measure the complex number
public double Module()
{
double temp;
temp = System.Math.Sqrt( x*x+y*y);
return temp ;
}
//use to measure the divergence of the complex number
//the number return is use to define the color of the affix's point
public int diverg()
{
int i=0 ;
Complex c = new Complex(x,y) ;

while (i<imax_iter&&c.Module()<MODUL_LIMIT)
{
c=c*c+this;//yes * and + are the operator we've just overload
}
return i;
}
}
}

So we have all the stuffs we need to decide if a complex number is a member of Mandelbrot’s set or not.
Now let’s use it in a Winform.
5 steps :

Step 1 In Visual Studio .net, create a new C# “Windows Application” project.
Step 2 Add a new object to the project (project window), a class(.cs file) names "complex". Then replace all the code of the file by the preceding complex class code.
Step 3 In the design view of the form1.cs add:
- A picture box named BoiteImage
- Four text boxes named respectively:
hgx(left and top X coordinate) default value:-0.5
hgy(left and top Y coordinate) default value:-1
bdx(right and bottom X coordinate) default value: 1.5
bdy (right and bottom Y coordinate) default value: 1
- A button named trace

If your not familiar with Visual studio: you will find all those stuff in the “tool box” window You can change the names and default values by right clicking + properties over the created objects. Then find the “name “ or “defaultvalue” properties in the “properties” window.

Step 4 In the project window double click on the ”trace” button. You are now in the Onclick event implementation method.
Put the following code into the “{ }”:

int nbPix=1000;
double diagDest;

int x,y;
Bitmap Imag;
Color col;
int iDiv;
Complex c= new Complex();

//define the complex plan zone
Complex cHG = new Complex(Convert.ToDouble( this.hgx.Text),Convert.ToDouble( this.hgy.Text));
Complex cBD = new Complex(Convert.ToDouble(this.bdx.Text),Convert.ToDouble(this.bdy.Text));
diagDest=Convert.ToDouble( this.hgx.Text)-Convert.ToDouble( this.bdx.Text);

//instantiate the bitmap
Imag = new Bitmap(nbPix ,nbPix);

//scan the bitmap
for(x=0;x= 255)
//if it converges it's black
col = System.Drawing.Color.FromArgb(255,0,0,0);
else //if it is not, it depends of the speed
col = System.Drawing.Color.FromArgb(128,iDiv,iDiv,iDiv);

//set the pixel color
Imag.SetPixel(x,y,col );
}
//draws the image
BoiteImage.SizeMode = PictureBoxSizeMode.StretchImage ;
BoiteImage.ClientSize = new Size(Imag.Size.Width, Imag.Size.Height);
BoiteImage.Image = (Image) Imag ;


Step 5 Now Hit F5 key and then click the « trace button » enjoy and change the range to explore the set!

That’s all folks
Sources and .exe on line soon !
Comments are welcome

Special thanks to my schoolmates Benoit and Jérôme .


 
Thursday, November 18, 2004
  SQL Analytical : Rollup
A few days ago, I started to introduce analytical SQL functions.
After "group by grouping sets" and "rank over", let's talk about "Rollup".

Let's suppose you have the following table :
create table SALES(
PRODUCT_NAME VARCHAR2(255 BYTE),
DAY NUMBER(2),
MONTH NUMBER(2),
YEAR NUMBER(4),
AMOUNT NUMBER(9)
)
Now, suppose you want to calculate the total amount for one day, the total amount for one month and for one year. You may use the "grouping sets" syntax. This is a powerfull feature which allow you many combinations. But have a look to this one:


select PRODUCT_NAME,DAY ,MONTH ,YEAR, sum(AMOUNT) from sales group by rollup (YEAR,MONTH,PRODUCT_NAME)

This
syntax will return the sale's amount for one month and one product then for all the month , this for each month and then the grand total.
Notice that you just need to specify your grouping level. Imagine your final application is something like a querying tool for instance an ASP .NET web form (I should talk about this in another post). You can propose your user a grouping level option button which modify dynamically the rollup field list, easily.

Now, let's suppose your table is not completed , some MONTH fields contains a NULL value. How can you make the difference between the real null value and the null value which is the mark of a group sum.
There is a solution which help to see the difference for a querying tool, the "grouping" function.

select PRODUCT_NAME,DAY ,MONTH ,YEAR, sum(AMOUNT), grouping(YEAR), grouping(MONTH),grouping(PRODUCT_NAME)
from sales
group by rollup (YEAR,MONTH,PRODUCT_NAME)

For instance the "grouping(YEAR)" column return 1 when the line is a sum for one year and the rest of the time. Then your Web form will be able to detect if the line is aggregate and on which level (you may want to change the font or color of the line) . You can also use it with a "decode" function for instance to put the text "Total" instead of the product_name. Let's try this :

select
decode(grouping(PRODUCT_NAME),1,'all product' ,PRODUCT_NAME),
decode(grouping(DAY),1,'all month',DAY),
decode(grouping(month),1,'all year', MONTH) ,
YEAR,
sum(AMOUNT)
from sales group by rollup (YEAR,MONTH,PRODUCT_NAME)

Ok That's all folks , hope this help !Any comments are welcome!



 
Monday, November 15, 2004
  Just another link today
Oracle Monster: Forums for Oracle DBAs and developers - Offers forums where you can get help with everything from SQL language and security to database design and optimization.
 
Friday, November 12, 2004
  A few Oracle and Microsoft links
Today I would like to list a few of my favourites web sites.

here is a good oracle sql reference :
http://www.lc.leidenuniv.nl/awcourse/oracle/server.920/a96540/toc.htm

Here is a direct link to Microsoft .Net framework reference on msdn:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/netfxanchor.asp .

here are the google archives of usenet groups on which I made a contribution:
comp.databases.oracle.server
microsoft.public.excel.worksheet.functions
microsoft.public.excel.misc
microsoft.public.excel
sybase.public.sqlanywhere.general
Good WE everybody
 
Tuesday, November 09, 2004
  Strange and usefull Oracle SQL structure
hello everybody,

Last week I talked a lot about how to get Oracle's data into Excel. I said that, in my opinion, Excel is not the right tool to re-structure and reformat datas. It is not an OLAP tool.
Today I would like to talk about a few Oracle specific SQL syntax that may be usefull for that: "rank over" and "group by grouping sets"

"rank over"
So what is this?
Here is a sample code:
Just imagine you have a table which contains the monthly turnover of the products: MONTHLY_TURNOVER with the following fields PRODUCT_NAME,MONTH,YEAR, AMOUNT.


select MONTH'/''YEAR', PRODUCT_NAME, Amount, rank() over(partition by MONTH, YEAR order by AMOUNT desc) Month_Rank from MONTHLY_TURNOVER order by YEAR asc, MONTH asc,Month_Rank asc;

This query returns all the products for each month, orders by decreasing amount of turnover with the rank of each product in the month.

This query does not make any filtering action. Instead, there is ordering and creation of information. The"rank()" syntax creates a new piece of information : the rank in the month of the product.


Now imagine you have 500 differents products. You may want to see only the 10 most important of each month. This may be obtained by the following syntax:

select * from (
select MONTH'/''YEAR', PRODUCT_NAME, Amount, rank() over(partition by MONTH, YEAR order by AMOUNT desc) Month_Rank from MONTHLY_TURNOVER order by YEAR asc, MONTH asc,Month_Rank asc)

where Month_Rank<10;

I suggest you to build this as an Oracle view and then to query it by filtering on the year field or by the period you are interested in.



"group by grouping sets"


Did you ever work with MS Access report or Crystal Report? Then you must have seen these features that permit you to make sums, averages or other aggregation functions at different levels in those reporting tools. For instance, you can calculate the sum of all the turnovers of your products year by year, month by month, and then product by product for one month.
You can do the same things directly with Oracle.

Using the same table as in the first paragraph, try the following:

select sum(AMOUNT ) AMOUNT , MONTH,YEAR, PRODUCT_NAME
from (MONTHLY_TURNOVER)
group by grouping sets ((MONTH,YEAR, PRODUCT_NAME),(MONTH,YEAR),(YEAR))
order by year, month, product_name;
you will have the following result assuming you have two products and one year :

AMOUNT MONTH YEAR PRODUCT_NAME
---------------------------------------------------------
10 1 2004 p1
20 1 2004 p2
30 1 2004
15 2 2004 p1
25 2 2004 p2
40 2 2004
. . .

60 12 2004
360 2004

As you can see, the line that sums all the turnovers of one month does not have any value for "product_name". The line that sums all the year does not have any value for "product_name" and "month".

I found this very usefull because if you have to do this kind of query usualy you need to use three "select from where " clauses and you need to repeat three times your "where" clause.
Personnaly, I used it in a view to sum surfaces for different real estate assets. For each building I get the sum of the rented and the free surface, and the total.


Ok that's all folks.

Hope this will help developers as it helps me!
Comments are welcome!



 
Tuesday, November 02, 2004
  From the datawarehouse to the chart (part 2)
Last week I introduce the MS Query feature of Excel.
Let's talk today about a few tricks to optimize its utilization with Oracle.

Ok first you may have notice that this a very slow feature. Changes to the source query are uneasy. You need to open the source query. Then to use an old fashion query defintion tool. And then to go back to the Excel file to finally realize that you have to change some criteria in the SQL code.

How to speed up this?

Use your knowledge of the database
Make Views.
It seems to be an easy-to-say thing but, to my point of view, this it is critical. I think that Excel by it self don't have to be a datamart and shouldn't. You should Use Oracle Views to reformat or re-structure your data. There is many standard and Oracle specific SQL statements which can help you for this (that is a good idea for a next post).
Use routine to change SQL.
You are the developper. You know where to get the information in the database.
Most of the time you define your queries in your fovarite Oracle tool and not in Excel or MS Query. So you don't need a wizard to explore the database. Instead you may need, as I, a quick way to seek-and-destroy bugs.

I prefer to use my own a VB statement (which will be not stored into the final file).
Here is the sub I use :

Sub createquery(strODBC, strSQL, strDestinationRange, strNAme)
With ActiveSheet.QueryTables.Add(strODBC, Destination:=Range(strDestinationRange))
.CommandText = strSQL
.Name = strNAme
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.Refresh BackgroundQuery:=False
End With
End Sub

strODBC is the an ODBC string something like :
ODBC;DSN=DSNName;UID=USer_ID;PWD=Password;DBQ=SCHEMA_NAME;"
strSQL is the SQL statement you want to execute here
strDestinationRange is something like "B2" or "$A$12:$H$52"

You should use this statement carefully at your own risq and, off course, fit it to your needs.

Notice that you may change the ODBC string structure, for instance if you omit thePassword excel will prompt you to logon. Notice that


Using parameters.

Parameters allow you to change criteria of a query without any VB code.
Here is the way I use parameters in MS query :
I use my favorite Oracle developpement tool and make a SQL query without parameters for instance :

select name from customers where max_ammount>1000
and min_amount <100


here is the versions with parameters

select name from customers where max_ammount>?
and min_amount < ?


Yes, there is no named parameters. Excel have specifical way to bind those things, just using order.

Try it, for instance with the preceding VB code, or with the MS Query tool.
When refreshing the data, Excel ask you to fill those parameters.

At any time you can specify the source for each parameters:

The first option is interesting. It allows you set the text of a question which will be asked to the user for this parameter.

Notice that when you use VB code to create a query with parameter, Excel gives default names to these parameters. If you want set your own names use the following syntax in a vb module :

Dim qt As QueryTable

Set qt = ActiveSheet.QueryTables("MyQuery")

qt.Parameters("Parameter1").Name = ("myFirstParam")

qt.Parameters("Parameter2").Name = ("mySecondParam")

All properties of parameters seems to be reachable by rightclick->parameters but the name which can be change only by code.

Charts

Now you know how to make get data from parameterized query over Oracle into your Excel workbook, I suggest you the following if you need to produce many charts from yout datawarehouse.

I - Let's suppose you have built a View describing the monthly 's turnover of your products. In a new excel sheet type-in the product id of one of your products, build a query like the following :

Select MonthNumber, turnover from v_monthly_turn where product_Id = ? and year = 2004

II - When the wizard prompt you for the parameter's value, select a cell which contains your product's ID and check the box to make this permanent.

III - When the data are returned select the range. Click on the chart button an choose your chart's style and location.

IV - Change your product's ID and refresh the data by right click->refresh data over the data range.

You may customise this:

Instead of a cell based parameter use a parameter whith a question like "What is the product ID?" . You may then set the "Refresh on file open" property to yes :(right click on the range then "properties") your file will then become a little decisional tool. And this without any VB code!

That 's all for today thank you for your attention.

All comments are welcome.











 
You are a developer and work with Oracle and Microsoft technologies? Have a look!
ATOM
How to:
Use updatable views in Access
Get data in Excel from Oracle 1
Get data in Excel from Oracle 2
Draw the Mandelbrot set using C#
Use the "Grouping Sets" SQl Syntax
Use the "Rollup" SQl Syntax
Use the "Rank over" SQl Syntax

Go to knol
When does the next bus pass?
Thanks
googled2cd966929769ab9
two lines in the datagrid header
Context saving with persistent datasets
.net webservice session
Winform, Web Services & credential
back to work
just a link
ARCHIVES
October 2004 / November 2004 / December 2004 / January 2005 / February 2005 / March 2005 / April 2005 / June 2005 / July 2005 / August 2005 / September 2005 / December 2005 / February 2006 / December 2006 / March 2009 /


Powered by Blogger

mboizeau.free.fr