14. September 2011 21:15

Team-Filter für hockeytoto.ch

Da ich dieses Jahr bei hockeytoto.ch mitmache und mich die etwas unübersichtliche Oberfläche gestört hat, habe ich mich heute hingesetzt und ein kleines Userscript für Greasemonkey geschrieben.

Select-Box um nach einer Mannschaft zu filtern

Das Script blendet auf der Tipp-Seite eine Select-Box ein, in welcher eine Mannschaft gewählt werden kann. Nach dieser Mannschaft wird die Tabelle dann gefiltert, d.h. man sieht nur noch die Matches in denen diese Mannschaft Heim- oder Gastmannschaft ist.

Gerade um später in der Saison Tipps abzugeben kann es sinnvoll sein die letzten Ergebnisse anzusehen. Aber auch sonst finde ich die Seite dadurch einfach übersichtlicher. Rvtl. bringt es ja irgendjemandem sonst auch noch etwas. Würde mich natürlich auch über Feedback freuen :-)

Um das Script nutzen zu können muss zuerst die Firefox-Erweitertung Greasemonkey installiert werden.

Links:


Comments
25. June 2011 18:59

Zum selektierten Wert springen (IE Bug)

Der Internet Explorer hat die Angewohnheit in einer <select>-Box den ausgewählten Wert nicht direkt anzuzeigen. Stattdessen werden immer nur die ersten Werte angezeigt. Der IE zeigt also folgendes:

Der ausgewählte Wert ist nicht sichtbar

Wobei ich eigentlich folgendes erwarten würde:

Der ausgewählte Wert ist als solcher erkennbar

Wenn der Benutzer scrollt, sieht er schon welcher Wert gewählt ist, die Liste springt jedoch nicht automatisch zum ersten ausgewählten Wert (wie das beispielsweise der Firefox macht).

Mit einer kleinen JavaScript-Funktion kann dies aber einfach nachgebaut werden, die Funktion erwartet den Namen der <select>-Box als Parameter, eine analoge Funktion für die ID lässt sich sehr einfach bauen:

[Pastie-Link]

Offenbar reagiert der IE auf dynamisch gesetzte Selektionen, warum er das nicht von sich aus macht, ist mir schleierhaft. Am einfachsten ist es wenn das Script beim laden der Seite aufgerufen wird:

<body onload="jumpToSelectedOptions(pizzaList);">

Evtl. ist das ja jemand anderem auch noch nützlich. Ich verwende die Funktion bei einer Auswahlliste die eine Mehrfachauswahl zulässt, dank dem “break” springt die Funktion einfach zum ersten gewählten Wert.


Tags:  HTML  JavaScript  Programming 
Comments
21. June 2011 17:58

PHP Unit Testing mit SimpleTest

SimpleTest in action

Seit letzter Woche habe ich SimpleTest im Einsatz und bin davon ziemlich begeistert. Das Framework bietet alles was man von einem konventionellen Unit-Testframework her kennt, wie diverse Assertion-Methoden oder Gruppierung von Testfällen zu Testsuiten. Daneben gibt es aber noch eine ganze Reihe von coolen Erweiterungen:

  • Es gibt einige vordefinierte Test-Reports, welche den Erfolg (oder Misserfolg) der Tests anzeigen. Wenn einem diese nicht genügend kann man diese (dank OO) ganz einfach erweitern. So habe ich meinen “persönlichen” Testreporter geschrieben, welcher mir neben den Details zu den Fehlern auch die Details zu den erfolgreichen Tests beschreibt (dazu muss man nur die Methode paintPass() überschreiben), das Resultat ist in obigem Bild ersichtlich.
  • Man kann auch sogenannte Web-Tests machen, d.h. man kann das Browserverhalten simulieren und so beispielweise automatisiert ein Formular ausfüllen und abschicken lassen, anschliessend dann das Ergebnis prüfen.
  • Das erzeugen von Mock-Objekten ist kinderleicht, das Framework bietet eine einfache Methode um eine “leere” Hülle eines Objekts zu generieren (z.B. einer Datenbankverbindung)

Das Tutorial führt einem durch die ersten Schritte, die API gibt den vollständigen Überblick. Durch die verschiedenen Reporter kann das gleiche Skript auch gebraucht werden um in einem automatisierten Build zu laufen, so wie man es z.B. von JUnit kennt.

Ich habe momentan alle meine Testfiles in einem Verzeichnis und habe mir deshalb ein simples Skript geschrieben, welche alle Tests ausführt:

[Pastie-Link]

Um jedes einzelne File jedoch immer noch separat ausführen zu können, include ich autorun.php nur genau dann, wenn ich das File direkt anspreche:

if (count(get_included_files()) == 1)
{
    require_once("includes/simpletest/autorun.php");
}

Ich kann das Framework also nur empfehlen!


Tags:  PHP  Unit Testing  Programming 
Comments
3. November 2010 07:43

Developers Shame Day: BB-Code selbstgemacht

Developers Shame Day

Via Twitter (weiss leider nicht mehr wer das geschrieben hat) bin ich auf einen Artikel vom php hacker gestossen, wo er dazu aufruft heute am “Developers Shame Day” mitzumachen und alte Codeschnippsel von sich zu posten: Beispiele von schlechtem Code für die man sich heute schämen sollte.

Einserseits um zu zeigen, dass jeder mal angefangen hat schlechten Code zu schreiben und allgemein sich einzugestehen, dass Fehler nun mal passieren und man selbst und vielleicht sogar andere davon profititieren können. Da mach ich gerne mit.

Das Stück Code das ich vorstellen möchte ist PHP-Code, welcher auf einer meiner alten Pages gelaufen ist. Jeder kennt ja die BB-Codes um Artikel oder Kommentare mit Formattierungsinformationen anzureichern. Ich habe meinen eigenen “Parser” dafür geschrieben, welcher die Codes in entsprechendes HTML umgewandelt hat.
Hier ein Auszug:
[Pastie-Link]

Die Idee dahinter war einfach, es gibt 2 Arten von Codes:

  • ohne Parameter wie z.B. Bold, also [b]fetter Text[/b]
  • mit Parametern wie z.B. URL, also [url=http://www.readmore.ch]Meine Webpage[/url]

Die parametrierbaren Codes erhielten im Anfangsarray den Text “!!REPLACER!!” welche dann anschliessend ersetzt wurde. Das mag ja alles noch gehen, wenn auch sich solche ein Parser mit Regular Expression um einiges schöner schreiben liess.

Wirklich stolz bin ich auf Zuweisungen à la “s” => “<s>”, “h1” => “<h1>”, wo sich mir heute die Nackenhaare aufstellen. Typisch war auch die schlechte Namensgebung der Variablen (anz oder sub/newsub) sowie die auskommentierten Stellen (“man weiss nie für was das mal noch gut sein kann”).


Comments
11. November 2009 11:06

The Go Programming Language

Today I came across a new programming language called Go, developed by Google

It is meant to be fast, but still garbage collected and type safe. They use pointers, but no pointer arithmetic.
The questions remains: Do we really need another C++-like language?

See Yourself:


Tags:  Programming 
Comments
21. October 2009 16:27

ODBC Hell

It is so easy: I have a testing environement where an OCI8-Driver is installed. Therefore I can use the OCI-Function if PHP to Bind Variables, get return values and everything is just fine.

Then on the production I needed to switch to ODBC, and thought: Easy just write this stuff for ODBC and you’re done.

Unfortunately the driver does simply not support return values of functions. The problem is, that there are updates in my function, so I can’t solve the problem using:

select function_name(param1,param2,param3,...) from dual

After giving up my return value, I wanted to run the function like that (in TOAD this is no problem):

begin :retval := function_name(?,?,?,?); end;

Afterwards you are giving an array of parameter to the PHP function odbc_execute, and this should work alright.

I tried hundrets of possibilities to run my function. Finally I gave up, made a procdure (which has no return value and vor sure ODBC has no support for OUT or INOUT-Vars). I resigned to have a return value (which should only be the number of updated rows).

I tried: begin procedure_name(?,?,?,?); end;

There was no reaction. My last try:

call procedure_name(param1,param2,param3,..);

This woked! So I need to use “call” and not using the parameter-array of ODBC but giving it directly into the call. I’m happy to get it working, but this costs me one day.

Is there any really working ODBC-Driver for PHP?

I gave up.

PS: Yes I know, there is a solution for my return value. In my procedure I could write the value into a temporary table. But I rather want to use a good driver (like the OCI8) than using such a temporary solution. I’m open to new ways of doing this.


Tags:  Oracle  PHP  PL/SQL  SQL  Programming 
Comments
21. October 2009 16:06

Brainfucked Logo

++++++++++[>++++++++++<-]>——-<++++++++++[»+++++++++++++«-]
»———«+++++[»>++++++++++«<-]»>—-«<++++++++++[»»+++««-]
»»++>+++++++++++++««<++++[»»»++++++++++«««-]»»»++++«.»
[««<.»»>-]<.«<.«++[»»»+++++«««-]»»»[«.»-][-]«««++
[»»»++++«««-]»»»-[««<.»»>-][-]«««++[»»»++++++++++«««-]
»»»-[«.»-]««<….»>….«.»>.«<.»…»[-]«««++++++++++
[»»»++++++++++«««-]»»»—.[-]«««++++++++++[»»»++++++++++++«««-]
»»»+.«….<.>…….<.<.»….<.«—-.+++..»>……..<.>….
<.<.»..«.»>.«<.»..»[-]«««++++++++[»»»++++++++++«««-]»»»-.
[-]«««++++++++++[»»»++++++++++«««-]»»».+++++.«…<.«……»>.
<.>.«.»…<.>…<.«—-.+++..»>….<.«…»>.<.>.«.»..«.»>.«<.».»
[-]«««+++++[»»»++++++++++«««-]»»».—..++++.«..«.»…….«.»..
«.»..«.<—-.+++..».>…<.«—-.+++»>..«.»….«.»..«.»..«.»>.«<.
»…….«.»…«<.»>…«.»..«.»..«.».«<.»>.«<—-.+++..».>.<.>..«.
»….«.»..«.»..«.»>.«<.»…….«.»..«.».«.»..«.»..«.»..«.».
«<.>.»…«<—-.+++».>…«.»….«.»..«.»..«.»>.«<.»…….«.»
…….«.»..«.»..«.»….«<..».>….«.»….«.»..«.»..«.»>.«<.»
…….«.»…….«.».<.>…«.».«<..».>…….«.»….«.».<.>…«.»>.
«<.»…….«.<…….>.>.>….«.>.>……….«.<….>.>.>….«.»>.«<.»»
[-]«««++++[»»»++++++++++«««-]»»»++++[««<.»»>-]««.

Nice isn’t it?

Well, but you’re asking what this is all? I will give you the related links as soon as my link-system is working. For now this little explanation should help you, otherwise google for “Brainfuck tutorial”.

Brainfuck is a very small (esoteric) programming language. It was design by a Swiss guy with the aim to write the smallest possible compiler for a Turing-complete language (his size is about 240 bytes).

And sure Brainfuck is Turing-complete.

The context of the language is a large array with (depending on the compiler and/or interpreter) about 30’000 array cells (each cell will be initalized with 0).

The 8 instructions:
> change the pointer to the next cell
< change the pointer to the last cell
+ increment the cell value
- decrement the cell value
[ begin of loop
] end of loop (a loop stops is the value of the actual cell is 0)
, read a value (input) into the actual cell
. Print out the ascii sign belonging to the cell value

Depending on that I will print you my bf-code of above again, this time with comments and so on:

 ____________________________________________
| ________ ____ |
| by / /| /\__ / /| |
| Odi /_______ / | / /\__ /___ / | |
| 2004 | | | |\__/ /\ | | | |
| | _ | | | _ \__/ / | | | |
| | | | | | | _| \/ | | | |
| | | | | __/ | | | |
| | | / | __/ | | / |
| |________ |/ |/ |____|/ |
|____________________________________________|

Brainfuck Pendant (commentent):

FIRST PLACE IS THE FILL IN COUNTER PLACE

++++++++++[>++++++++++<-]>——- = 95 in 2nd place (ASCII for “_”) (pos:2)
<++++++++++[»+++++++++++++«-]»——— = “|” (124) in 3th place (pos:3)
«+++++[»>++++++++++«<-]»>—- = “/” (47) in 4th place (pos:4)
«<++++++++++[»»+++««-]»»++ = SPACE (32) in 5th place (pos:5)
>+++++++++++++ = “New Line” (13) in 6th place (pos:6)
««<++++[»»»++++++++++«««-]»»»++++ = 44 in 7th place (times to repeat “_”) Use as Counter place (pos:7)


//START Line 1
«. = Print SPACE at the beginning of line 1 (pos:5)
 » = Change Pointer to 7 (pos:7)
[««<.»»>-] = Print 44 times “_” (pos:7)
<. = Change to 6th place and print NewLine (pos:6)
//END Line 1

//START Line 2
«<. = Change to 3th place; print “|” (pos:3)
«++[»»»+++++«««-]»»» = Fill Counter with 10 (pos:7)
[«.»-] = print 10 SPACE (pos:7)
[-] = Clean 7th place to 0 (pos:7)
«««++[»»»++++«««-]»»»- = Set counter place to 7 (pos:7)
[««<.»»>-] = Print 8 “_” (pos:7)
[-] = Clean 7th place to 0 (pos:7)
«««++[»»»++++++++++«««-]»»»- = Set counter place to 19 (pos:7)
[«.»-] = Print 19 SPACE (pos:7)
««<…. = Change to 2nd place; print 4 “_” (pos:2)
»>…. = Change to 5th place: print 4 SPACE (pos:5)
«. = Change to 3rd place: print “|” (pos:3)
»>. = Change to 6th place: print NewLine (pos:6)
//END Line 2


//START Line 3
«<. = Change to 3rd place; print “|” (pos:3)
»… = Change to 5th place; print 3 SPACE (pos:5)
 »[-] = Clean 7th place (pos:7)
«««  = Change pointer to 1 (pos:1)
++++++++++[»»»++++++++++«««-]»»»—. = Set 7th position to 98 (stands for “b”) and print it (pos:7)
[-] = Clean 7th place (pos:7)
«««  = Change pointer to 1 (pos:1)
++++++++++[»»»++++++++++++«««-]»»»+. = Set 7th position to 121 (stands for “y”) and print it (pos:7)
«…. = Change to 5th place; print 4 SPACE (pos:5)
<. = Change to 4th place; print “/” (pos:4)
>……. = Print 8x SPACE (pos:5)
<. = Print “/” (pos:4)
<. = Print “|” (pos:3)
»…. = Print 4 SPACE (pos:5)
<. = Print “/” (pos:4)
«—-. = Print “" (_{95} minus 3 = \{92}) (pos:2)
+++.. = Print 2 “_” (pos:2)
»>…….. = Print 8x SPACE (pos:5)
<. = Print / (pos:4)
>…. = Print 3 times SPACE (pos:5)
<. = Print “/” (pos:4)
<. = Print “|” (pos:3)
 ».. = Print SPACE (pos:5)
«. = Print “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 3

//START Line 4
«<. = Change to 3rd place; print “|” (pos:3)
 ».. = Change to 5th place; print 3 SPACE (pos:5)
 »[-] = Clean 7th place (pos:7)
«««  = Change pointer to 1 (pos:1)
++++++++[»»»++++++++++«««-]»»»-. = Set 7th position to 79 (stands for “O”) and print it (pos:7)
[-] = Clean 7th place (pos:7)
«««  = Change pointer to 1 (pos:1)
++++++++++[»»»++++++++++«««-]»»». = Set 7th position to 100 (stands for “d”) and print it (pos:7)
+++++. = Set 7th place to 105 (stands for “i) (pos:7)
«… = Print 3 SPACE (pos:5)
<. = print “/” (pos:4)
«…… = Print 5 “_” (pos:2)
»>. = Print a SPACE (pos:5)
<. = Print “/” (pos:4)
>. = Print SPACE (pos:5)
«. = Print “|” (pos:3)
»… = Print 3 SPACE (pos:5)
<. = Print “/” (pos:4)
>… = Print 3 SPACE (pos:5)
<. = Print “/” (pos:4)
«—-.+++ = Print “" (decrease “_” about 3 back to the orgin) (pos:2)
.. = Print 2 “_” (pos:2)
»>…. = Print 4 SPACE (pos:5)
<. = Print a “/” (pos:4)
«… = Print 2 “_” (pos:2)
»>. = Print a SPACE (pos:5)
<. = Print a “/” (pos:4)
>. = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print SPACE (pos:5)
«. = Print “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 4

//START Line 5
«<. = Change to 3rd place; print “|” (pos:3)
 ». = Change to 5th place; print 3 SPACE (pos:5)
 »[-] = Clean 7th place (pos:7)
«««  = change position to 1 (pos:1)
+++++[»»»++++++++++«««-]»»». = Print “2” (50) (pos:7)
—.. = Print 2x “0” (48) (pos:7)
++++. = Print “4” (52) (pos:7)
«.. = Print 2 SPACE (pos:5)
«. = Print a “|” (pos:3)
»……. = Print 9x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
<—-.+++ = Print a “" (pos:2)
.. = Print 2x “_” (pos:2)
 ». = Print a “/” (pos:4)
>… = Print 3x SPACE (pos:5)
<. = Print a “/” (pos:4)
«—-.+++ = Print a “" (pos:2)
»>.. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 5

//START Line 6
«<. = Change to 3rd place; print “|” (pos:3)
»……. = Change to 5th place; print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
»… = Print 3x SPACE (pos:5)
«<. = Print a “_” (pos:2)
»>… = Print 3x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
«<. = Print a “_” (pos:2)
»>. = Print a SPACE (pos:5)
«<—-.+++ = Print a “" (pos:2)
.. = Print 2x “_” (pos:2)
 ». = Print a “/” (pos:4)
>. = Print a SPACE (pos:5)
<. = Print a “/” (pos:4)
>.. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 6

//START Line 7
«<. = Change to 3rd place; print “|” (pos:3)
»……. = Change to 5th place; print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
«<. = Print a “_” (pos:2)
>. = Print a “|” (pos:3)
»… = Print 3x SPACE (pos:5)
«<—-.+++ = Print a “" (pos:2)
 ». = Print a “/” (pos:4)
>… = Print 3x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 7

//START Line 8
«<. = Change to 3rd place; print “|” (pos:3)
»……. = Change to 5th place; print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
»……. = Print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print a SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«<.. = Print 2x “_” (pos2)
 ». = Print a “/” (pos:4)
>…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ».. = Print 2x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 8

//START Line 9
«<. = Change to 3rd place; print “|” (pos:3)
»……. = Change to 5th place; print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
»……. = Print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
<. = Print a “/” (pos:4)
>… = Print 3x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
«<.. = Print 2x “_” (pos2)
 ». = Print a “/” (pos:4)
>……. = Print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
»…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
 ». = Print a SPACE (pos:5)
<. = Print a “/” (pos:4)
>… = Print 3x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 9

//START Line 10
«<. = Change to 3rd place; print “|” (pos:3)
»……. = Change to 5th place; print 7x SPACE (pos:5)
«. = Print a “|” (pos:3)
<……. = Print 7x “_” (pos:2)
>. = Print a “|” (pos:3)
>. = Print a “/” (pos:4)
>…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
>. = Print a “/” (pos:4)
>………. = Print 10x SPACE (pos:5)
«. = Print a “|” (pos:3)
<…. = Print 4x “_” (pos:2)
>. = Print a “|” (pos:3)
>. = Print a “/” (pos:4)
>…. = Print 4x SPACE (pos:5)
«. = Print a “|” (pos:3)
»>. = Print NewLine (pos:6)
//END Line 10

//START Line 11
«<. = Change to 3rd place; print “|” (pos:3)
»»[-] = Clean 7th place (pos:7)
«««++++[»»»++++++++++«««-]»»»++++ = 44 in 7th place (times to repeat “_”) Use as Counter place (pos:7)
[««<.»»>-] = Print 44 times “_” (pos:7)
««. = Change to 3rd place and print “|” (pos:3)
//END Line 11

Brainfucked wishes


Tags:  Programming  Brainfuck 
Comments
24. August 2007 12:54

MS Access: Let lines in Reports grow with it’s content

The problem is the following: You create a report with MS Access with a text field. To display the whole text, you have to set the “CanGrow” property to “Yes” (on the section and on the text-field). When running the report that has vertical lines as column seperator you have an ungly effect: The line keeps its size, as this has been fixed in the design view.

One might think that the easy solution is to adjust this length at runtime. First of all I need to declare what “runtime” means. As this problem occures in every “Detail”-Section we must dive in the events a section provides. There are three of them “OnRetreat”, “OnFormat” and “OnPrint” (apart all the mouse events, which are defenitly not suitable).

The Retreat-Event occurs “when Microsoft Access returns to a previous report section during report formatting” (Source: VBA Help). Not exactly what we’re looking for.

The Format-Event occurs “when Microsoft Access determines which data belongs in a report section, but before Access formats the section for previewing or printing”. It sounds good, but at this point we don’t have our data in the section and are therefore unable to determine the correct height.

Finally the Print-Event “after data in a report section is formatted for printing, but before the section is printed”. Here we are, we have our data which is not yet printed. The problem is that at this point all elements are already formatted, all we can do is add new elements and that’s why we can’t just adjust the height of each line by setting it via

 Me.myLine.Height = Me.Height '''this does not work in the OnPrint event, myLine has already been formatted

The simple solution is to draw a new line and use your already placed line as a template:

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
    Dim EndOfLine As Double
    EndOfLine = Me.Height       ''height of section (where the line stops)

    ''becasue it's not allowed in such a late state to change lines, we draw new one's based on the old
    ''myLine
    Me.Line (Me.myLine.Left, 0)-(Me.myLine.Left, EndOfLine)

End Sub;

Tags:  MS Access  VBA  Programming 
Comments
30. June 2007 01:49

MS Access and not updatable Recordsets

The whole thing is just plain stupid: Someone in the department I work in has created an MS Access Database to track our customers. Above this application are some forms to insert the data. Now we already have much of the data in various excel sheets etc. So my task was to write a function (or method or sub or whatever you call it in your world) to get some values from an excel sheet and insert it to a form, just like a user would do it. Like that the user has the possibility to check and change the data before it gets saved in the database. Now if you bind the form elements to parts of a query, Access gets your data as a so called snapshot via MS Jet (your communication channel to the DB). Snapshot data is not updateable, so if you try to assign your own values to form elements an error message pops up and that’s it.

My first solution was to ignore that fact and simply update my data directly to the database. But then all nice features like the “undo” option (to reset a record) or the possibility to check values before they get inserted are lost. The solution I came up is simple, but you need to check your status very exact to keep a usable form.

I have a form with my data, I have a save button, I have an exit button and I have an update button. There is a special button to start the gathering of data from the excel sheet. Now If you want to change the value of a textbox on the form you need to cut the textbox off the data (ControlSource = ""), then you can freely change the value.

Now you can’t simply update the current record, because the textbox is no longer in the recordset. This means that you have to update the value directly in the database when the save button is pressed. Then reattach the ControlSource and Requery and Repaint your form.

When you want to Undo your changed, just don’t save your values in the DB and reassign the ControlSource and Refresh the form, the old value will appear.


Tags:  MS Access  Programming 
Comments
14. May 2007 14:49

Convert fixed length column to Excel

I had to convert the output from sqlplus to an excel sheet. The problem was, that I had no influence on the creation, so I could spool the file directly to excel.

All I got were spool files like that:

      CLASS_ID SUPER_CLASS_ID   COUNT(*)
============== ============== ==========
       128           8765         18
       128           8765        131
       128           8765          7

My idea was to take the line used to seperate the column titles and the data as the data that gives me the length of each column (refered as the column line in my function below). Then just simply extract a block from start to end (as given) based on the gathered column length information.

Maybe someone can use this piece of VBA code:

Public Sub convertFixed()
    Dim sFile As String
    Dim iCount As Long
    Dim iSubCount As Long
    Dim iLastCount As Long
    Dim i As Integer
    Dim Length() As Integer
    Dim sValue As String

    Dim iStart As Integer
    Dim iEnd As Integer
    Dim iColumn As Integer


    ''clear previous data
    Cells.ClearContents

    ''choose the file with the windows file dialog
    With Application.FileDialog(msoFileDialogFilePicker)
    .AllowMultiSelect = False
    .Title = "Choose log file to convert"
    .InitialFileName = ThisWorkbook.Path
    .InitialView = msoFileDialogViewDetails
    .Filters.Clear

    ''the filter is set to .log .spool and .txt files
    .Filters.Add "Log file", "*.log, *.spool, *.txt"

    .ButtonName = "Load"
    If .Show = -1 Then
        sFile = .SelectedItems(1)
    Else
        ''stop execution if no file is selected
        Exit Sub
    End If
    End With


    ''we need the following informtion (gather with InputBoxes)
    ''line to scan the column lengh (space delimiteted) -> line number
    ''begin of block (line number)
    ''end of block (line number)
    iStart = InputBox("Enter line number where block starts:", "Line number of Start")
    iEnd = InputBox("Enter line number where block ends:", "Line number of End")
    iColumn = InputBox("Enter line number of fixed length specification", "Line number for fixed length")

    ''the first loop is to get the correct column length
    'open the file
    Open sFile For Input Access Read As #1
    iCount = 1
    ''loop until end of file (EOF) is reached
    Do Until EOF(1)
    Line Input #1, sLine
    If (iCount = iColumn) Then
        ''exit if the column line (to scan the length) is reached
        Exit Do
    End If
    iCount = iCount + 1
    Loop
    ''close the file
    Close #1

    iCount = 0
    iSubCount = 1
    iLastCount = 0
    ''sLine now contains a line that gives us the fixed length of the columns
    sLine = RTrim(sLine)
    Do Until iSubCount > Len(sLine)
    If (Mid(sLine, iSubCount, 1) = " " Or iSubCount = Len(sLine)) Then
        ''the Length array stores the length of each column (needs to be ReDim'ed with each new column)
        ReDim Preserve Length(iCount)
        Length(iCount) = iSubCount - iLastCount
        iLastCount = iSubCount
        iCount = iCount + 1
    End If
    iSubCount = iSubCount + 1
    Loop

    ''open the file to extract the block based on the column length stored in the Length-Array
    Open sFile For Input Access Read As #1
    iCount = 1
    iSubCount = 1

    ''loop until the end of the block is reached
    Do Until iCount > iEnd
    Line Input #1, sLine
    iLastCount = 1
    If (iCount >= iStart) Then
        For i = 0 To UBound(Length)
            sValue = Trim(Mid(sLine, iLastCount, Length(i)))
            ''prevent application errors with adding of "'" in front of special characters
            If (Left(sValue, 1) = "=" Or Left(sValue, 1) = "-" Or Left(sValue, 1) = "+") Then
                sValue = "'" & sValue
            End If
            ''insert the data to the current Excel sheet
            Cells(iSubCount, i + 1).Value = sValue
            iLastCount = iLastCount + Length(i)
        Next i
        iSubCount = iSubCount + 1
    End If
    iCount = iCount + 1
    Loop
    ''close the file
    Close #1

End Sub

Tags:  Excel  VBA  Programming 
Comments
27. December 2006 00:00

Excel to CSV with Python

I wanted to handle a simple task: convert a bunch of XSLs to CSVs. Well I wrote a small Script in VBScript and it worked. Then I needed to change the List separator, so I did that in my System settings, and then my Script didn’t work anymore, because it just ignored my changed settings.

I googled a lot and didn’t find the solution (only people with the same problem). It seems that VBScript (or WSH) is using it’s own locale that you can not change.

So I began to look for alternatives. Python can handle the COM interface when you install PyWin32 (the version must match the python version you’re using). So I just rebuild my script with python and it’s COM-Interface. Et voil�: it takes the user defined settings and converts my files in the way I want them.

#import win32 stuff
from win32com.client import Dispatch
#import other needed
import glob,sys,os

path = os.path.split(sys.argv[0]) #gather the path of the script
path = path[0]
path = path + '\\' #append \ at the end of path (when using *NIX you must use / instead
files = glob.glob('*.xls') #get list of files

xlApp = Dispatch("Excel.Application") #create Excel COM-Object
xlApp.DisplayAlerts = False
for file in files:
    xlWB = xlApp.Workbooks.Open(path + file)
    xlWB.SaveAs(path + file.replace(".xls",".csv"), 6 ) #6 = xlcsv
    xlWB.Close()
xlApp.Quit()
del xlApp

Tags:  Programming  Python 
Comments
12. December 2006 00:00

SQL Start-Script generator

Sometimes it’s so simple:

import glob
files = glob.glob('*.*');
f=open('start_script.sql', 'w')
f.write('PROMPT This is an automatic generated start script\n');
f.write('PROMPT\n');
f.write('SPOOL start_script.LOG\n\n');
for filename in files:
    if filename == 'start_script.sql':
        continue
    f.write('PROMPT Starting script ' + filename + '\n');
    f.write('@@' + filename + '\n');
f.write('\nPROMPT\n');
f.write('PROMPT Finished.\n');
f.write('SPOOL OFF\n');
f.close();
exit();

Explanation:

First get a file list of the current directory (glob.glob(‘.’), this won’t return you directories since they don’t have an extension, if your files doesn’t have an extension, either: your fault). Then open a file called start_script.sql which will held our start-script (pretty self-explanatory). Then we generate a “@@” line for each file (this means if you have non-SQL-files in that directory you have to clean-up your script or edit it that it only takes .sql files (tip: glob.glob(‘*.sql’)). The start-script itself is excluded but the python script will be included (can easily be made excluded as well). After the loop the file gets closed and that’s it.


Tags:  Python  SQL  Programming 
Comments
24. September 2006 16:44

Images Titles for Firefox users

The W3C Standard describes, that to a HTML-Images tag () there is a must-attribute “alt” that describes the alternate text if the images can not be displayed. MS Internet Explorer also uses this attribute to show a so called tooltip, this is a text that is showed when you move your mouse over an element (in this case over the image).

Other browsers use the title-attribute instead, because other elements don’t have the alt-attribute, but they are also able to show a tool-tip (e.g. anchor-Tags).

Now there are many many many many (did I already figure out that I mean many?) developers or web designer, who do not care about that kind of stuff. They test their pages with IE and that’s it. An example for such a page is the SAP booking page in the company I work for. Many people get angry because they don’t use IE and don’t get this tooltip. On our SAP site this is really annoying because the whole navigation is made by some icons with meaningless look so the tooltip is the only way to know what the button really does. Therefore there are user that changed back to IE because they thought Firefox behaves wrong. I wrote this little 5-line script to copy the content of the alt-attribute to the title-attribute. Install it using the Firefox-Extensions Greasemonkey, and that’s it.

My Images-Title User-JavaScript

More information about Greasmonkey and how to program with it on the Dive Into Greasemonkey page.


Comments
11. April 2005 00:00

Release Hostages

Problem

There are 7 (this could be optional maybe) hostages. They will be jailed into 7 rooms and they cannot communicate during this time. They can discuss 1 hour before they get jailed. They know that the will be choosen randomly every day to go into an 8th room, where the can turn on and off a light.

When someone can say surly that every hostage was a least once in this room, they are all released.

At the beginning the light is turned off.

Idea

Every hostage has a week, so there are anz_host weeks as a minimum to free the hostages. If a hostages get’s into the anz_host++ room, he/she turn’s on the light.

Everybody who comes in this week after the turn up of the light happens in the room, knows that the hostage week_num has been in the room. Maybe it get’s more evective if I use a larger window than a week, because then, the chance that more other hostages sees who’s got in the room is larger, but the time will grew up a lot.

Well let’s give it a try.

btw: You have to watch carfully which hostage knows what…

Code

See pastie for the complete code

Result

I tried my program on Windows and Linux (just to get better results, because of the random number implemention and the time function, be careful if you want to port the code, the obove should work well with windows)

My solution seems to be ok, an average of 90 days with the basic set. But as you can see there are a lot of option to change the basic set and then my solution still works well.

Use the option -H or /? to get help with the options.

PS: I’m not yet good at the effective programming and I’m sure there is an easier way to do things I did in my code. Feel free to tell me what you think (via mail until my comment system works)

PPS: Special thanks to my brother Dani (www.swissbytes.de), who gave me the idea to this problem and wrote a perl script to simulate his solution (well he wasn’t that successful, because his average is about 500 days I think and surly his script ran much slower than my fast C application ;) )

Creative Commons

This work is licensed under a Creative Commons License.


Tags:  Programming  C 
Comments