dinsdag, november 22, 2005

Scripting Word

Sometimes you write a simple piece of code, and you just look at it… and it is beautiful ;-) Here is how to use a template word document and modify it on-the-fly from ASP.. problem is you need the Word object on the Server, which is why I didn’t use it, but in stead.. I used an even greater tool — but I didn’t write that one myself.. more about that later.

 

<%
const wdReplaceAll = 2
Set objWord = server.CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open(server.mappath("/files") & "/inputfile.doc")
Set objSelection = objWord.Selection
objSelection.Find.Text = "strname"
objSelection.Find.Forward = TRUE
objSelection.Find.MatchWholeWord = TRUE
objSelection.Find.Replacement.Text = "Peter De Rop"
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
objSelection.Find.Text = "strtitle"
objSelection.Find.Replacement.Text = "Modifying Word"
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
objSelection.Find.Text = "strdate"
objSelection.Find.Replacement.Text = date
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
objDoc.SaveAs server.mappath("/files") & "/outputfile.doc"
objWord.application.Quit False
%>

woensdag, oktober 05, 2005

Context operators in Business Objects (part 4)

Foreach and Forall revisited
=Average(<Sales revenue> ForEach <Quarter>) ForAll <Year>
What does this formula do ?
To understand it, first consider the following tables :
Table Year and Sales Revenue
Table with Year quarter and Sales Revenue


Imagine, we want to show the number 2,023,954 in the first table  (so we can compare the Sales revenue per year to the Average Sales Revenue per quarter for that year. With the standard calculations in Business Objects, such is impossible. This is the situation where you need Context Operators. When adding the formula =Average(<Sales revenue) to the table to the left, the result would be the same number as the column with the Sales Revenue itself, since in that table Business Objects can only consider that value to calculate the average. So we say the context of the average in that case is just the “sales revenue”. In case we wish to include the <Quarter> also into that calculation, we would need to include an input context : Foreach or In. Both will do the same in this case, the only difference is the way they work. Foreach is able to add dimensions to the calculation (key word is ADD) This means that in a Foreach, the dimensions already in the table are always taken into account. The formula would then become : =Average(<Sales revenue> foreach <Quarter>) This tells the average function to include the Quarter in the calculation together with Year which is already in the table. The “In” Operator can do the same, but then the function would have to be : =Average(<Sales Revenue> in (<Year>,<Quarter>)) this needs to be done because In ignores the dimensions already in the table. The resulting table :
Year Quarter and average with contextThis is what we call an Input Context. This kind of context operator is added inside the brackets.
If we needed to show the number at the bottom  of the above table, (3,032,267) then we would need an output context, since we want to show the average for the entire Year. the formula would then be the one I stated at the beginning of this article : =Average(<Sales revenue> ForEach <Quarter>) ForAll <Year>
This second operator is used in this case as the Output Context operator The same is possible with “In Report” as the output context. The resulting table :
Table Year Sales Revenue with Output context

That should be the end of this topic.

Did this information help you ? Look.. a 'Donate' button on the right side :)

dinsdag, juli 26, 2005

Dreamweaver, Ubuntu PHP and MySQL

First, let me remind you that I’m not an expert at Ubuntu, so the following is again, the result of a couple of buckets of sweat !

Have been fiddling around with PHP and MySQL for a while — didn’t work out at first.

then I found why I couldn’t get them to work properly…

1) MySQL is setup in such a way, you cannot connect to it from the outside.

solution : change the my.cnf file (on my system, it was located in /etc/mysql/)

find a line that says “skip-networking” (without the quotes) and put a # in front of it.
there, now you can connect to MySQL from a graphical shell like MySQL Administrator on a Windows machine ;-) of course, MySqlCC on Linux is just as good.

2) PHP is set up to ignore MySQL completely

solution : un comment two lines in php.ini (on my system it was located in /etc/php4/apache2/) watch out though … they give some sample lines, but one of them has
a spelling mistake in it… it should be extension=mysql.so and extension=gd.so for some reason, one of those lines is written msql.so.

3) rights have to be set correctly

I used these pages as a reference : sourceforge and my favorite dev.mysql.com

4) Dreamweaver functions have to be installed on the server to be able to test your connection

somewhere on your windows computer, you should be able to find a folder called _mmServerScripts. This folder needs to be copied into the folder where your PHP application will be created (I don’t remember if DWMX2004 did it automatically — but I remember copying it manually).

Some useful commands :

to restart mysql (you need to restart it when adding or changing userrights)
sudo killall mysqld  (to stop it)
sudo mysqld start (to start it)

when changing ini files and conf files you need to restart apache … without restarting linux, this is done with :
sudo /etc/init.d/apache2 restart

 

 

 

maandag, juli 18, 2005

The movie copi�r

I buy a lot of movies. For years, I bought tons of VCR cassettes. Being a real collector, I watched them each over a dozen times over. And then disaster struck. My VCR would destroy a video when you watched it and during the time you were watching pressed rewind. I do that all the time — missed something, so a quick rewind to rehear what that person was saying. of course — you don’t know the video was destroyed until you watch it a second time.

I found myself in the DVD Era pretty soon after that hideous mishap.

In the mean time, my DVD collection is growing — I buy a lot of DVD’s. And again, as before, I watch them regularly. I salvaged some of my VCR’s as DIVX some time ago, but I never got round to putting them on a DVD — so I was happy to find that it is quite easy to do. I found the procedure to convert DIVX into DVD on Afterdawn. (You will need a powerful machine — and a lot of time to get the job done though)

After the mishap with my VCR collection, I have grown somewhat paranoid.. So for the moment I’m creating backup DVD’s of some of my most loved DVD’s… I didn’t know copying a DVD was so simple.

For those who want to know :

download two software packages :

DVDdecryptor : which reads and writes DVD’s (free)
DVDShrink : which allows you to throw away the things you don’t need (subtitles and audio in albanian or Arabic or any other language you don’t understand) (free)

First use DVD decryptor in “File” Mode to get all of the files from the DVD decrypted and zone removed onto the HD. Next use DVD Shrink to backup or reauthor the files on your disk … last, write the ISO file which is the result of DVD Shrink back to a DVD… using DVD decryptor in Write ISO mode…

easy as 123 

 

woensdag, mei 11, 2005

SQL Reporting Services

Last week, my coach told me, it would be a good idea to have a look at SQL Reporting Services. The Microsoft equivalent (as he called it) of Business Objects.

First thing I did was install a VMWare machine with SQL and the Reporting Services. Compared to installing Business Objects, this is quite straightforward. The installation procedure is very much like every installation procedure by Microsoft. The result was, that I had reporting services up and running in about 5 minutes. During this installation, the system asks you if you want to use the demo database.

Visual Studio.NET is required to create the reports — a definite difference with Business Objects.

SQL reporting services

My Conclusions. SQL Reporting Services has nothing to do with Business Objects. They do somewhat the same, but their target audience is very different. In business Objects, an end user can build a report
and use it as he or she wishes. In SQL Reporting Services, all a user can do with a report is set some filters and drill down on data. Building a report is done by a specialised service — or some
well trained people who design the RDL files. Thorough knowledge of SQL queries is a must, thorough knowledge of the database is a must — knowledge of Visual Studio.NET helps out a lot.
In business objects, the designer of a BO Universe gives objects logical names and groups objects together — in these RDL files, the designer has to choose all of the fields from the database — fields can be located anywhere.

To me it looks like SQL Reporting Services is the kind of thing where a central design team designs all of the reports.. users have to nag them to get reports changed — BO is the kind of
program where users can create their own reports and work a lot more flexibly/dangerously(they can make their own analysis errors) — but at a cost. Business Objects is not exactly a cheap tool.

anyway, learning more about SQL Reporting services as we speak.

zondag, april 17, 2005

SubQuery's in Business Objects

The title may seem complex, but the issue is simple.

Lets say you wanted to see the Sales Revenue per Store, but only for Stores located in a State that had a Sales Revenue over 7.000.000 $.

In that case, you would have to produce a query that would return all of the States over 7.000.000 $, and based on that query, obtain all of the stores you needed. The Stores by themselves don’t have such a high Sales Revenue, so you can’t get this in one go.

Here is how :

A simple query Containing Sate, Storename and Sales Revenue

This would return us the Stores and their Sales Revenue (all stores). So next, we need to perform a Filter on the State, setting a Sub-query as a source.

Filter on state, using a Subquery

bo_screen3[2]

The result is as follows :

Result of the Query

The stores listed only come from states with a Sales Revenue over 7000000$ — just as required.

Great stuff isn’t it ?

Beware : Universes have a parameter that limit the maximum inlist values. Furthermore, some databases have limits on the maximum inlist values.

The most common number is 999. The parameter on the universe that sets this is : MAX_INLIST_VALUES and is set, by default to 256.

maandag, april 11, 2005

topcom wireless lan on Linux

Here is how to install a topcom wireless lan module under Ubuntu Linux (Hoary)
I’m not a Linux specialist, so this is the result of a couple of buckets of sweat.

Installation succeeded on Hoary (Ubuntu Linux) 2.6.10-5-386
First make sure you have all necessary packages.
Under Ubuntu Linux, use Synaptic, to install :
linux-wlan-ng
wireless-tools
linux-386
linux-kernel-headers (for the version of kernel you have -- mine was 2.6.10-5-386)
gcc
gcc-3.3
gcc-3.3-base
libgcc1

yeah -- it's a long list ... but you will need it to compile...

next, surf to :
http://linux-lc100020.sourceforge.net/
to get it working, I downloaded version 0.13 -- I also tried
it with version 0.14, but to no avail
once you got the tar.gz file into a folder, unpack it (tar zxvf zd1201-0.13.tar.gz)
don't compile yet, it won't work... you need more.

Next... tricky one...

download ipw2100-1.1.0.tgz from http://sourceforge.net (go through search and type ipw2100)
untar it.. (tar zxvf ipw2100-1.1.0.tgz
copy the files
ieee80211.h
and
ieee80211_crypt.h
into the headerfolder : /usr/src/linux-headers-2.6.10-5/drivers/net/wireless
(this step is required for this specific wireless module)
remember the file you untarred... zd1201-0.13.tar.gz ?
go back to it and modify zd1201.c (yeah you really have to)
replace every instance of ieee802_11 with ieee80211 -- shitty job...
run make
run make install
copy the zd1201.fw and zd1201-ap.fw files into the
/lib/hotplug/firmware folder and
the /usr/lib/hotplug/firmware folders...
run depmod -a
run insmod zd1201.ko

(added thanks to Stephen Pike)

or -- if that gives an error on symbols
use modprobe -v zd1201 instead

I then rebooted the system (yeah -- not really required)
System>Administration>Networking should now list your wireless connection.
change the properties to make it active and choose the right accesspoint
use the iwconfig, dmesg and ifconfig commands to check your configuration..
ifup wlan0 and ifdown wlan0 should allow you to start and stop the wlan module..

lots of luck !

zondag, maart 27, 2005

Website of Jarne

I put a small website online for our son Jarne. There are some pictures from his birthcard there, plus a photogallery. Enjoy.

zaterdag, maart 26, 2005

Yeah Baby !

On 24 March 2005 (as in the day before yesterday) my baby son was born.
His name is Jarne, he weighs 3Kg and measures 50cm.
One of these days I will post some pictures.

dinsdag, maart 22, 2005

The best Raidlevel (Part 2)

So as it turns out, Raid 5 is a very good Raidlevel, but it is not very good at writing. Raid 1+0 is very good, but it is rather expensive. Is that all there is to it ? No. If you have read one of my previous articles, you might have read that a harddrive’s speed is influenced by Latency and Seek. If you combine that story with this particular story, then you might find out there is more to it.

The two main ways of communicating with a disk are Sequential and Random. In a sequential environment, large chunks of data are being transferred (e.g. : 64K or 128K or bigger) This occurs most on file and print servers. In a random environment, larege amounts of small chunks of data are being transferred to the disk (e.g. 4k) This occurs most on a database server.  If you think a little further on this, you might consider that Raid 5 has to do about twice the work for writing a chunk of data compared to Raid 1+0 (Raid 5 has to read existing data, read existing parity, calculate the parity, write new data, write new parity).

In that case you might come to the same conclusion as Database manufacturers and database gurus. Raid 5 is not a good thing to combine with a database. It will flood the Raid 5 with small chunks of data and that poor Raid 5 has to do twice the work a Raid 1+0 has to do at writing.

A clear conclusion is : Avoid Raid 5 in a database environment. But most people forget that Exchange is also a database.

My recommendation : If you are going to install a server, and you are considering to install 3 disks in Raid 5 and put your exchange server on it — why not consider a little further, add 1 extra disk, use Raid 1+0 in stead. The result is remarkable : Twice the speed, Twice the fault tollerance, twice the speed at reconstruction, more than twice the speed during a disk failure.

Good and Bad Popups

So you want to use popups ? Of course you do, opening a window is a right for everybody — but you might have discovered, that there are things around called popup blockers.

Both Internet Explorer and Mozilla Firefox include tools to block popups, furthermore, software exists that blocks all popups. As a programmer, it is impossible to take these last into account.

So, what is the difference between good and bad popups.

When an html document is opened in the browser, much depends on the zone where a page is opened. If a document is opened in the zone of the local computer, there is a small difference between Internet Explorer and Firefox. Internet Explorer will consider all scripting in a page that is launched in the Local Computer Zone as a potential hazard, and will show a warning.

Popup warning
Firefox does not do this. Once the page is put on the internet, this problem does not exist (example).

A good popup, is launched by a click-event. or a doubleClick event

A bad popup is launched by an onLoad event,  onMouseOver event, onContextMenu event or onMouseOut event

This means that most “accidental” calls of popups are blocked. The only one that surprised me somewhat is the onContextMenu. But then again, right clicking a link is something we do to force
the opening of a link in a different target window, so it makes sense.

vrijdag, maart 18, 2005

The best Raidlevel (Part 1)

Ask 10 system engineers, which is the best Raid level and 8 will answer : Raid 5. The other two will ask the smart question :“for which application ?”

This is the start of a somewhat long article I think. The discussion is long and interesting.

When you try to evaluate the different Raid levels, you should be concerned with the kind of data transfers that will occur on it. Is it going to be a system with mostly Sequential transfers like a File-Server ? or is it going to be a system with mostly Random transfers like a Database Server ? Or is it going to be a mixture, and in that mixture, which kind of transfer occurs most ?

First, lets assume we are going to perform 400 Writes and 600 reads on a series of Raidsets. This means that the system will be working with mostly Reads, but still quite some Writes to deal with as well.

What would be the result for a Raid 0 ? (afterwards we can compare with Raid 1+0 and Raid 5

Let’s assume we have three Raid 0 Raidsets. each totalling in 72 GB Net Storage

In a Raidset with 2 disks, the total number of Reads and Writes gives you the number of IO’s so in this case, the number of IO’s (for 400 writes and 600 reads) is 1000 IO’s
When you only have 2 disks, you split those IO’s across the 2 disks, giving a total of 500 IO’s /disk

When we have 3 disks, we gain some speed because the total number of IO’s can be split across more disks. This gives you now 250 IO’s / disk

With 8 disks, the result will be 125 IO’s / disk

2 disks of 36GB = 1000/2 = 500 IO’s per disk
4 disks of 18GB = 1000/4 = 250 IO’s per disk
8 disks of 9GB = 1000/8 = 125 IO’s per disk

And what about Raid 1+0 ?

In a Raid 1+0, everything that has to be written has to be written twice. Reads can be performed across all disks. 
Since we now have to take into account the writing, the number of IO’s to process is (400*2)+600 = 1400 IO’s / 4 =  350 IO’s /disk.
With 8 disks, this will give you 175 IO’s /disk  With 16 disks : 87 IO’s /disk

4 disks of 36GB = 1400 /4 = 350 IO’s per disk
8 disks of 18GB = 1400/8 = 175 IO’s per disk
16 disks of 9GB = 1400/16 = 87 IO’s per disk

And Raid 5 ?

Raid 5 is a different story. In raid 5, each time you write something, the parity has to be calculated and written to the disks. But more importantly, to be able to write the parity and the data, a Raid 5 has
to read the data and parity that exists on the disk already –  change it and write the data. The result is that the number of IO’s on Raid 5 for this same writing is much higher.

For 600 Reads and 400 writes, Raid 5 will take (4 * 400) + 600 = 2200 IO’s

3 disks of 36GB  = 2200 / 3 = 733 IO’s / disk
5 disks of 18GB = 2200/5 = 440 IO’s / disk
9 disks of 9 GB = 2200/9 = 244 IO’s / disk

So, it is true, that 3 disks in Raid 5 is not as expensive to have fault tollerance… but is it really cheap ? If I add 1 extra disk to it and create a Raid 1+0 in stead of a Raid 5, I get the same capacity –  I double my speed and I double my fault tollerance. (in a Raid 1+0 with 4 disks, when you have a second disk failing, you still have a 2/3 chance your system is up and running. With Raid 5, your system is down.

More on a next issue.

 

 

 

dinsdag, maart 15, 2005

Raid 0+1 is not 1+0

For years I’ve been trying to explain the difference between these two, only to find a lot of people thinking it is the same thing. Here is the difference:

Raid 0 + 1In a Raid 0+1 system, first a Raid 0 is applied on the disks. The result of this operation is speed. Next, on top of the Raid 0 (usualy done by software) a second Raid is applied, which is a Raid 1. The result of this second Raid is for security. When you look at this configuration, you might think everything is nice and dandy, but this is actually the worst kind of config, and is never put on hardware Raid controllers. This is very bad. First : Security – When one disk fails, the system has 2 disks down (both halves of a Raid 0) this means that only the remaining Raid 0 is still on-line. If a disk fails in that Raid 0 you are in SH.T. This means that only the second disk of the failed Raid 0 can fail (1 chance out of 3) and your system is still working. Second :  Speed. Again, if the system goes bad, and a disk fails, you are working at half the speed. And when you restore, the system has to copy the RaidSet from one Raid 0 onto the other Raid 0 (all disks have to work).

A much cleaner way to do this is Raid 1 + 0 :

Raid 1 + 0Two Raid 1 are created. Across those two Raid 1, a Raid 0 is created. The result may not be obvious at first, but if you fail a disk, the system still works on 3 disks(faster) if a disk fails, 2 chances out of 3, your system is still ok. When you are rebuilding, it just copies 1 disk (of the failed mirror) to the other.

This is the kind of Raidset which is usually implemented in hardware Raid controllers (if yours does not… get another).

HP (Compaq) has been advertising for years that they were using 0+1 whereas they were really using 1+0 which is far superior.

You can tell very easily if your system is using 0+1 or 1+0 .. if you remove a disk and put it back.. if only 2 disks are working to perform the restore : 1+0 .. otherwise 0+1.

maandag, maart 14, 2005

Context operators in Business Objects (part 3)

In Body and In Report.

A nice quirk in Business Objects, is the calculation in %. It adds an extra column to your table, which contains a formula :

=<Sales revenue>/Sum(<Sales revenue>) ForAll <Year>

which is based on the ForAll operator. The result is the following table :Sales revenue per Year

When you add a dimension to this table (let’s say the Quarter)

Sales Revenue per Year and Quarter


I don’t know, but I think my counting still works.. it now says 100 % where it should be closer to 450 %. This is due to the fact that the context operator is still the same. It should now be
=<Sales revenue>/Sum(<Sales revenue>) ForAll (<Year> , <Quarter>). But Business Objects does not update the formula. What you can do now is remove the column with the calculation and reinsert it. But hey, there is a better way :

Insert the following formula :
=<Sales revenue> In Body /Sum(<Sales revenue>) In Report

This means that BO will now take the sales revenue in the Body of the table which is 2.6 million for the first, 2,27 million for the second item etc. and divides that number by the total Sales Revenue. I wonder why the people who built this program did not use this particular formula. I found it in their own documentation.  Oh.. before I forget..here is the result.

Solved

 

More on a next item !

vrijdag, maart 11, 2005

Context operators in Business Objects (part 2)

Foreach and Forall allow you to add or remove dimensions to or from a calculation.

ForeachtableWhen you look at the table to the left, you will see that the third column shows the same as the column next to it. The third column contains Min(<Sales revenue>), still it returns the same, which is logical. The context of the calculation is just “Year”. This means that The minimum Sales Revenue based on one number returns only that number.

With the ForEach operator, we can now add a dimension to the context. The formula is now : Min(<Sales revenue> foreach <Quarter>). The minimum is now calculated per Quarter as well. Returning the following table :

Table showing minimum in the context of Year and Quarter

This means, that (for the calculation) the quarter has been included in the calculation.

Forall is the exact opposite. If you have a table containing Year, Quarter,Month, Sales Revenue, then min(<Sales Revenue> forall <Month>) will remove Quarter from the equation and return the minimum by year and Quarter only.

Next issue :

In Body and In Report, which are interesting when you use percentages.

dinsdag, maart 08, 2005

Context operators in Business Objects (part 1)

This is quite a topic. It is not covered in any of the courses, but the possibilities it offers are quite impressive.
To start with, BO offers 7 context operators :
  • in
  • Foreach
  • Forall
  • in Body
  • in Block
  • in Report
  • currentpage
In this first part, I shall be explaining the In operator.
Let’s say you show a table (based on the e-Fashion Universe) containing Year, Quarter and Sales Revenue. As a default, the Sales Revenue is shown “in the context” of Year and Quarter. If you were to create a table with only the year and Sales Revenue, then the context of the Sales Revenue would be the Year. This is what we call the “Input Context”.
When you create a table, containing Year, Quarter and Sales Revenue and you create a Break on the table. next you create a sum on the Sales Revenue, then BO will write a sum at the end of each Year. This is called the “Output context”.
Table with year quarter and salesrevenue with a break on Year
Let’s now say that you need to show that minimum in an extra column, so you can compare the Sales Revenue to the Minimum Sales Revenue for that Year.
Then the formula would be :
Min(<Sales Revenue> In (<Year>,<Quarter>)) In <Year>
The first “In” indicates that the Minimum Sales Revenue has to be calculated in function of Year and Quarter, but has to be shown by Year, which is taken care of by the second “In” operator.
In a next item : Foreach and Forall

vrijdag, maart 04, 2005

Bug in Business Objects 6.0

If you read previous articles, you may know that I play around a lot with Business Objects. Once and again, I run into strange bugs, and when I do, I write a little article about it. Here is another weird bug in BO 6.

When you save a document (including different reports) as HTML, all works out nicely. But when you open that report in Internet Explorer, and click the download link in the bottom right corner, to lauch BO to view the document, somehow it messes up the entire layout of the buttonbars. Each Buttonbar shows on its own line. Probably one of those things that need solving in version XII -- version XI does not include a Windows base reporting tool -- only web.

donderdag, maart 03, 2005

Dreamweaver and RSS

In a previous article, I wrote about the RSS features of Firefox. Of course, being into webdesign, cool tools like a tool to integrate RSS and Dreamweaver gets me fantasizing. Going to test it soon, but if you can't wait

go to the download site

Ever wanted to syndicate web content fast and easily? MX RSS Reader-Writer is a 2 in 1 solution. First of all, it allows you to import RSS (Really Simple Syndication) files and integrate them in your website design and secondly it allows you to export database information into RSS format. This way you will be able to increase the traffic on your site by gathering and distributing your news in a wisely manner.

maandag, februari 28, 2005

Calculating the speed of harddisks (part 6)

What about Raid you might ask ?

Indeed, when you put a harddrive together with a couple of other drives, it
improves the performance. The best way, by far, is Raid. Some Raidlevels will give you better performance, while others improve security above all else.



Raid 0

Raid 0 is of course the most dangerous Raidset, and should be avoided in any situation where the data is critical. But when it comes to performance, it is the best there is. Multiply the speed of one disk, times the number of disks. If that number does not exceed the speed of your scsi bus, then you are smiling.



Raid 1 and 1+0

Raid 1 and 1+0 are often referred to as being the most expensive Raidsets. This is partly true, since you have to buy twice the number of HD's to get half the capacity. But they deliver outstanding performance.


consider this :

1 disk delivers 20MB/s. When configured in a mirror, the system is able to do "Split Seeks" which means that it can read from two disks at the same time. So 2 disks give you 40MB/s when reading. When writing, the speed will not go up, since everything has to be written twice. If your diskset performs 60 writes and 40 Reads, then you get 180 IO's. On a Raid 0 this would have been 100 IO's.. but on Raid 5, it would require 220 IO's -- I will clarify on a next installment. Cheers !