Thursday, October 21, 2010

Windows 7 laten slapen met een script

How to put windows 7 to sleep in a script
For English version, see below

In een DOS script kun je b.v. na het afronden van het script de PC laten slapen. Tot nu toe lukte dat niet omdat mijn PC steeds in hibernation ging i.p.v. slaap.

Om de PC te laten slapen moet je eerst hibernation uitschakelen. Dit kan vaak lastig zijn, maar Microsoft komt je hier te hulp. Op deze pagina zie je twee kleine programmaatjes waarmee je hibernation kunt uitschakelen en aanschakelen. Door eerst het hibernation uitschakelen programma te draaien kun je het volgende commando gebruiken om je PC te laten slapen aan het einde van een DOS script.

rundll32.exe powrprof.dll,SetSuspendState 0,1,0

Nadat je het Fixit programmaatje voor het herstellen van hibernation hebt gedraaid, zal het boven genoemde commando de PC weer in hibernation brengen.

How to put your PC to sleep through a DOS command

When I tried to put my PC to sleep through a DOS command, it used Hibernation, not the sleep (suspend) mode. In order to force the PC to use the sleep mode, you have to disable hibernation. This turning hibernation on/off has been made easy by Microsoft through two Fixit tools, which can be found here. After you ran the disable hibernation tool, the command below will put your PC to sleep. If you want to change back to use hibernation, just run the other tool and the command will put your PC back into hibernation.

Command:
rundll32.exe powrprof.dll,SetSuspendState 0,1,0

Success.

Sunday, October 17, 2010

Waarom ik niet met EON in zee ging

Ruim een week geleden werden wij gebeld door de EON met een aanbieding voor energie met een zakelijk contract. Volgens de EON kunnen ZZP'ers nu ook een zakelijk contract afsluiten waardoor je véél goedkoper uit bent.

Wij hebben een contract voor gas en stroom via GreenChoice. Voor gas betalen we zo rond de 56 cent per m3 en voor stroom zo rond de 22 cent per kwh. Ik ben heel tevreden over GreenChoice, maar dat neemt niet weg dat ik open sta voor alternatieven.

Tijdens de "sales pitch" liet de EON verkoper regelmatig vallen dat de EON speciaal voor ondernemers een tarief hanteert van slechts 7,7 cent per kwh en 34 cent per m3 gas, alles inclusief BTW. Dat zijn forse besparingen. Eigenlijk te mooi om waar te zijn.... En dat is het ook. Tijdens het afrondende gesprek noemde de verkoper nog snel een paar bedragen met getallen achter de komma en het werd zo geformuleerd dat ik dacht dat het over mijn huidige prijzen ging.

Nog voor de overeenkomst van de EON binnen was ben ik eens gaan zoeken. Wat blijkt GreenChoice heeft een basis prijs van 6,6 cent per kwh. Weliswaar zonder BTW, maar omgerekend kom je slechts een fractie hoger uit dan de 7,7 cent van de EON. Met gas was dat precies het zelfde. Die uiteindelijke prijs van 22 cent per kwh heeft te maken met allerlei extra belastingen die over die 6,6 cent worden geheven.

Ik bespaar graag als dat kan en het EON contract is misschien wel iets goedkoper, maar door deze misleiding tijdens de sales pitch heb ik alle vertrouwen in EON verloren. Binnen een paar dagen, je hebt 7 dagen bedenktijd, opgebeld om de overeenkomst ongedaan te maken. Toen de medewerker vroeg waarom ik de overeenkomst ongedaan wilde maken vertelde ik dat ik me misleid voelde en er geen basis van vertrouwen meer was. "Kan ik aangeven dat u tevreden bent met uw huidige leverancier en dat u daarom niet wilt overstappen?" vroeg de medewerker. "Nee, ik voel me belazerd!", reageerde ik. Die optie zat niet in de keuze voor het opzeggen van een overeenkomst.

Mooi hoor al die CRM systemen. In de maandelijkse rapportage staat nu dat ik niet ben overgestapt "Omdat ik zo tevreden ben met mijn huidige leverancier". Hoe kan een onderneming nu leren van de reacties uit de markt als ze hun oren afsluiten voor de werkelijke redenen?

Tuesday, October 5, 2010

Van lijst naar matrix en terug

English version below.

Tabellen maken met tekst opgelost.
Bij het omzetten van eenvoudige lijsten naar matrices via draaitabellen liep ik tegen het probleem aan dat de draaitabellen uitgaan van hoeveelheden en mijn tekst waarden omzetten naar een aantal. Daarom was ik op zoek naar een alternatief voor draaitabellen waarbij de tekst gegevens in de matrix komen te staan in plaats van de aantallen.

Bij het zoeken zag ik dat anderen ook met dit probleem kampten en dat er geen bruikbare antwoorden bij zaten. Op de Microsoft site staat een heel eenvoudig macrootje dat alleen met enkele vaste waarden werkt. Ik heb dat macrootje als basis gebruikt om van een lijst met 3 kolommen een matrix te maken.

Al een hele tijd geleden had ik ook een macrootje gevonden, en aangepast waarmee je een matrix kunt omzetten naar een lijst met 3 kolommen. Dat staat iets verder beneden.

English version

Solved converting a list to a matrix
For some time I was looking to solve a problem with pivot-tables. When I convert a list to a pivot table the resulting text data is converted to a summary or a count. In my situation most of the fields either showed zero's or one's instead of the text. When I searched the web, I realised that I wasn't the only one with this problem and no one seemed to have a solution. That is why I used a very rudimentary example from a microsoft site and made it more flexible for me. It takes a 3 column list and converst it to a two dimentional matrix. The beauty is that here my text data remains as it was. So this is an alternative to the pivot-tables if you want to keep your text fields untouched. A long time ago I also found a VBA macro to convert a matrix in a table. I can't remember where I found it, so I can't give attributes here. I modified that Macro and included it here as well.

Matrix naar lijst (Matrix to list conversion)

Hier begin ik met een matrix met de opleidingen aan de bovenkant en de medewerkers aan de linker kant.
Het macrootje maakt hier de lijst met 3 kolommen van.

Here I start with a matrix with courses on top and employees on the left. The macro creates a 3 column list.



















Lijst naar Matrix (List to matrix conversion)

Hier maak ik van een lijst met 3 kolommen een matrix. De gegevens in 3 kolommen MOETEN beginnen bij vakje A2, B2 en C2. en het resultaat komt rechts van kolom E.

Here in convert the 3 column list to a matrix.

The data in the columns has to start at cells A2, B2 and C2. The resulting matrix is built to the right of column E.





Code to Convert a matrix to a 3 column list and back.

Nederlandse gebruikers moeten waarschijnlijk de comma's (,) veranderen in punt-comma (;).

Sub BuildTable()
'Cell A1 = Left Labels, Start with your data in Cell A2
'Cell B1 = Top Labels, Start with your data in Cell B2
'Cell C1 = Values, Start with your data in Cell C2
'Table starts in Cell F1
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Dim ListRow, TableRow, TableColumn As Integer
Dim TableEntry As String
Dim CellToFill As Range
'Prepare the X and Y-axes
Range("B2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("F1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
MYLastRowAddress = Range("F65536").End(xlUp).Address
ActiveSheet.Range("$F$1:" & MYLastRowAddress).RemoveDuplicates Columns:=1, Header:=xlNo
Range("F1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("G1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("F1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("F2").Select
ActiveSheet.Paste
MYLastRowAddress = Range("F65536").End(xlUp).Address
Application.CutCopyMode = False
ActiveSheet.Range("$F$2:" & MYLastRowAddress).RemoveDuplicates Columns:=1, Header:=xlNo
MYLastColAddress = Range("G1").End(xlToRight).Address
Range("F2").Select
'Fill in the values
ListRow = 2
Do Until Cells(ListRow, 1).Value = ""
' Get table entry from third column of list.
TableEntry = Cells(ListRow, 3).Value
' Get position of product name within range of row titles.
TableRow = Application.Match(Cells(ListRow, 1), _
Range("F2:" & MYLastRowAddress), 0)
' Get position of product size within range of column titles.
TableColumn = Application.Match(Cells(ListRow, 2), _
Range("G1:" & MYLastColAddress), 0)
Set CellToFill = Range("F1").Offset(TableRow, TableColumn)
' If there's already an entry in the cell,
' separate it from the new entry with a comma and space.
If CellToFill.Value <> "" Then CellToFill.Value = _
CellToFill.Value & ","
' Add the new entry to the cell.
CellToFill.Value = CellToFill.Value & TableEntry
ListRow = ListRow + 1
Loop
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub


Sub ReversePivotTable()
' The output table will have three columns.
Dim SummaryTable As Range, OutputRange As Range
Dim OutRow As Long
Dim r As Long, c As Long

On Error Resume Next
Set SummaryTable = ActiveCell.CurrentRegion
If SummaryTable.Count = 1 Or SummaryTable.Rows.Count < 3 Then
MsgBox "Select a cell within the Matrix.", vbCritical
Exit Sub
End If
SummaryTable.Select
Set OutputRange = Application.InputBox(prompt:="Select a SINGLE cell for the 3-column output", Type:=8)
' Convert the range
OutRow = 2
Application.ScreenUpdating = False
OutputRange.Range("A1:C3") = Array("Left Labels", "Top Labels", "Values")
For r = 2 To SummaryTable.Rows.Count
For c = 2 To SummaryTable.Columns.Count
OutputRange.Cells(OutRow, 1) = SummaryTable.Cells(r, 1)
OutputRange.Cells(OutRow, 2) = SummaryTable.Cells(1, c)
OutputRange.Cells(OutRow, 3) = SummaryTable.Cells(r, c)
OutputRange.Cells(OutRow, 3).NumberFormat = SummaryTable.Cells(r, c).NumberFormat
OutRow = OutRow + 1
Next c
Next r
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub


Here is an example on how to create a table with 3 values for each entry (see picture below)

Sub BuildTripleTable()
'Cell A1 = Left Labels, Start with your data in Cell A2
'Cell B1 = Top Labels, Start with your data in Cell B2
'Cell C1 = Values1, Start with your data in Cell C2
'Cell D1 = Values2, Start with the data in Cell D2
'Cell E1 = Values3, Start with the data in Cell D2
'Table starts in row 1 of "MatrixColumn"
TopLabels = "B2"
LeftLabels = "A2"
FirstValue = "C2"
SecondValue = "D2"
MatrixColumn = "H"
MatrixHeader = "I" 'Select ONE column to the right of the MatrixColumn
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Dim ListRow, TableRow, TableColumn As Integer
Dim TableEntry As String
Dim CellToFill As Range
'Prepare the X-ax
Range(TopLabels).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range(MatrixColumn & "1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
MYLastRowAddress = Range(MatrixColumn & "65536").End(xlUp).Address
ActiveSheet.Range(MatrixColumn & "1:" & MYLastRowAddress).RemoveDuplicates Columns:=1, Header:=xlNo
Range(MatrixColumn & "1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range(MatrixHeader & "1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range(MatrixColumn & "1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
'Prepare the Y-ax
Range(LeftLabels).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range(MatrixColumn & "2").Select
ActiveSheet.Paste
'Left Values have been Pasted.
'Remove Duplicates
MYLastRowAddress = Range(MatrixColumn & "65536").End(xlUp).Address
Application.CutCopyMode = False
ActiveSheet.Range(MatrixColumn & "2:" & MYLastRowAddress).RemoveDuplicates Columns:=1, Header:=xlNo
'Duplicate the Y-ax the First time and mark the duplicated entries with -1
Range(MatrixColumn & "2").Select
LeftColumnSourceRange = MatrixColumn & "2:" & Range(Selection, Selection.End(xlDown)).Address
Range(LeftColumnSourceRange).Select
Selection.Copy
Range(MatrixColumn & "65536").End(xlUp).Select
ActiveCell.Offset(1, 0).Activate
ActiveSheet.Paste
Application.CutCopyMode = False
For Each rcell In Selection
rcell.Value = rcell.Value & "-2"
Next
'Duplicate the Y-ax a second time and mark the duplicated entries with -2
Range(LeftColumnSourceRange).Select
Selection.Copy
Range(MatrixColumn & "65536").End(xlUp).Select
ActiveCell.Offset(1, 0).Activate
ActiveSheet.Paste
Application.CutCopyMode = False
For Each rcell In Selection
rcell.Value = rcell.Value & "-3"
Next
'Sort the tripple data in the left column
Range(MatrixColumn & "2").Select
MyWorkSheet = ActiveSheet.Name
MYLastRowNumber = Range(MatrixColumn & "65536").End(xlUp).Row
MyRange = MatrixColumn & "2:" & MatrixColumn & MYLastRowNumber
Range(MatrixColumn & "2").Select
Range(Selection, Selection.End(xlDown)).Select

ActiveWorkbook.Worksheets(MyWorkSheet).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(MyWorkSheet).Sort.SortFields.Add Key:=ActiveCell.Range _
("A1:A" & MYLastRowNumber - 1), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets(MyWorkSheet).Sort
.SetRange ActiveCell.Range("A1:A" & MYLastRowNumber - 1)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range(MatrixColumn & "2").Select
'Fill in the Data from Column 3 on the first row
MYLastColAddress = Range(MatrixHeader & "1").End(xlToRight).Address
MYLastRowAddress = Range(MatrixColumn & "65536").End(xlUp).Address
ReadColumn = 3
RowOffset = 0
ListRow = 2
Do Until Cells(ListRow, 1).Value = ""
' Get table entry from third column of list.
TableEntry = Cells(ListRow, ReadColumn).Value
' Get position of product name within range of row titles.
TableRow = Application.Match(Cells(ListRow, 1), _
Range(MatrixColumn & "2:" & MYLastRowAddress), 0)
' Get position of product size within range of column titles.
TableColumn = Application.Match(Cells(ListRow, 2), _
Range(MatrixHeader & "1:" & MYLastColAddress), 0)
Set CellToFill = Range(MatrixColumn & "1").Offset(TableRow + RowOffset, TableColumn)
' If there's already an entry in the cell,
' separate it from the new entry with a comma and space.
If CellToFill.Value <> "" Then CellToFill.Value = _
CellToFill.Value & ","
' Add the new entry to the cell.
CellToFill.Value = CellToFill.Value & TableEntry
ListRow = ListRow + 1
Loop
'Fill in the Data from Column 4 on the second row
ReadColumn = 4
RowOffset = 1
ListRow = 2
Do Until Cells(ListRow, 1).Value = ""
' Get table entry from fourth column of list.
TableEntry = Cells(ListRow, ReadColumn).Value
' Get position of product name within range of row titles.
TableRow = Application.Match(Cells(ListRow, 1), _
Range(MatrixColumn & "2:" & MYLastRowAddress), 0)
' Get position of product size within range of column titles.
TableColumn = Application.Match(Cells(ListRow, 2), _
Range(MatrixHeader & "1:" & MYLastColAddress), 0)
Set CellToFill = Range(MatrixColumn & "1").Offset(TableRow + RowOffset, TableColumn)
' If there's already an entry in the cell,
' separate it from the new entry with a comma and space.
If CellToFill.Value <> "" Then CellToFill.Value = _
CellToFill.Value & ","
' Add the new entry to the cell.
CellToFill.Value = CellToFill.Value & TableEntry
ListRow = ListRow + 1
Loop
'Fill in the Data from Column 5 on the third row
ReadColumn = 5
RowOffset = 2
ListRow = 2
Do Until Cells(ListRow, 1).Value = ""
' Get table entry from fifth column of list.
TableEntry = Cells(ListRow, ReadColumn).Value
' Get position of product name within range of row titles.
TableRow = Application.Match(Cells(ListRow, 1), _
Range(MatrixColumn & "2:" & MYLastRowAddress), 0)
' Get position of product size within range of column titles.
TableColumn = Application.Match(Cells(ListRow, 2), _
Range(MatrixHeader & "1:" & MYLastColAddress), 0)
Set CellToFill = Range(MatrixColumn & "1").Offset(TableRow + RowOffset, TableColumn)
' If there's already an entry in the cell,
' separate it from the new entry with a comma and space.
If CellToFill.Value <> "" Then CellToFill.Value = _
CellToFill.Value & ","
' Add the new entry to the cell.
CellToFill.Value = CellToFill.Value & TableEntry
ListRow = ListRow + 1
Loop
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub






Success, Robert