Active X controls werken niet meer in excel

Na een update van Windows bleken mijn active x controls in excel niet meer te werken.
Gelukkig is er google.

C:\Users\[user.name]\AppData\Local\Temp\Excel8.0\MSForms.exd

C:\Users\[user.name]\AppData\Local\Temp\VBE\MSForms.exd

C:\Users\[user.name]\AppData\Local\Temp\Word8.0\MSForms.exd

Of course the application (Excel, Word…) must be closed in order to delete this file.

Link naar originele oplossing.

Een proces beëindigen met visual basic

Omdat ik vrij veel gebruik maak van interactie tussen de verschillende office produkten, komt het wel eens voor dat er een proces blijft hangen. De applicatie zal dan veelal een fout vertonen in de vorm van ‘Switch to, retry, cancel’.

Wanneer ik vanuit mijn vba of vb6 code een instantie van excel/word,… creëer, dan zal ik (een beetje zoals de dispose van c# – of meer recent de using code block van c#) het gecreëerde proces gaan verwijderen. (dispose iemand?).

Maar in een oudere taal als VB6 bestaat er zo geen dispose of using.

Wat ik dan gebruik is een terminator (goed gevonden toch de naam?..)

In een module die dus mTerminator noemt heb ik onderstaande code:
Het volstaat in jouw programma om de TerminateEXE met de naam van het af te sluiten proces op te roepen.

Attribute VB_Name = "mTerminate"
Option Explicit

Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long

Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * 260
End Type

Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type

Private Const PROCESS_TERMINATE = &H1
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_READ = 16
Private Const TH32CS_SNAPPROCESS = &H2

Private Function CheckVersion() As Long
Dim tOS As OSVERSIONINFO
tOS.dwOSVersionInfoSize = Len(tOS)
Call GetVersionEx(tOS)
CheckVersion = tOS.dwPlatformId
End Function

Private Function GetEXEProcessID(ByVal sEXE As String) As Long
Dim aPID() As Long
Dim lProcesses As Long
Dim lProcess As Long
Dim lModule As Long
Dim sName As String
Dim iIndex As Integer
Dim bCopied As Long
Dim lSnapShot As Long
Dim tPE As PROCESSENTRY32
Dim bDone As Boolean

If CheckVersion() = VER_PLATFORM_WIN32_WINDOWS Then
'Windows 9x
'Create a SnapShot of the Currently Running Processes
lSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If lSnapShot < 0 Then Exit Function
tPE.dwSize = Len(tPE)
'Buffer the First Processes Info..
bCopied = Process32First(lSnapShot, tPE)
Do While bCopied
'While there are Processes List them..
sName = Left$(tPE.szExeFile, InStr(tPE.szExeFile, Chr(0)) - 1)
sName = Mid(sName, InStrRev(sName, "\") + 1)
If InStr(sName, Chr(0)) Then
sName = Left(sName, InStr(sName, Chr(0)) - 1)
End If
bCopied = Process32Next(lSnapShot, tPE)
If StrComp(sEXE, sName, vbTextCompare) = 0 Then
GetEXEProcessID = tPE.th32ProcessID
Exit Do
End If
Loop

Else
'Windows NT
'The EnumProcesses Function doesn't indicate how many Process there are,
'so you need to pass a large array and trim off the empty elements
'as cbNeeded will return the no. of Processes copied.
ReDim aPID(255)
Call EnumProcesses(aPID(0), 1024, lProcesses)
lProcesses = lProcesses / 4
ReDim Preserve aPID(lProcesses)

For iIndex = 0 To lProcesses - 1
'Get the Process Handle, by Opening the Process
lProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, aPID(iIndex))
If lProcess Then
'Just get the First Module, all we need is the Handle to get
'the Filename..
If EnumProcessModules(lProcess, lModule, 4, 0&) Then
sName = Space(260)
Call GetModuleFileNameExA(lProcess, lModule, sName, Len(sName))
If InStr(sName, "\") > 0 Then
sName = Mid(sName, InStrRev(sName, "\") + 1)
End If
If InStr(sName, Chr(0)) Then
sName = Left(sName, InStr(sName, Chr(0)) - 1)
End If
If StrComp(sEXE, sName, vbTextCompare) = 0 Then
GetEXEProcessID = aPID(iIndex)
bDone = True
End If
End If
'Close the Process Handle
CloseHandle lProcess
If bDone Then Exit For
End If
Next
End If
End Function

Public Function TerminateEXE(ByVal sEXE As String) As Boolean
Dim lPID As Long
Dim lProcess As Long

lPID = GetEXEProcessID(sEXE)
If lPID = 0 Then
Exit Function
Else
lProcess = OpenProcess(PROCESS_TERMINATE, 0, lPID)
Call TerminateProcess(lProcess, 0&)
Call CloseHandle(lProcess)
TerminateEXE = True
End If

End Function

Controle op ISBN met VB(A)

Een ISBN nummer ofte International Standard Book Number bevat net zoals een bankrekening, btw nummer, barcode,… een welomschreven structuur.

De juistheid van het nummer kan men met onderstaande functie controleren.

Function test_isbn(isbn) as boolean
Dim vl_isbn1 As Integer
Dim vl_isbn2 As Integer
Dim vl_isbn3 As Integer
Dim vl_pos As Integer

test_isbn = 0

If IsNull(isbn) Then
Exit Function
End If

If Len(isbn) = 13 Then
If Not IsNumeric(Left$(isbn, 12)) Then
Exit Function
End If
vl_isbn2 = Val(Right(isbn, 1)) ' controlegetal = laaste getal van de isbn

vl_isbn1 = 0
For vl_pos = 1 To 12
If vl_pos Mod 2 = 0 Then
' indien de modulus van de positie 0 is (dus even is, het getal op die positie maal 3)
vl_isbn1 = vl_isbn1 + Mid(isbn, vl_pos, 1) * 3
Else
' is de positie oneven, nemen we de waarde van het getal op die positie
vl_isbn1 = vl_isbn1 + Mid(isbn, vl_pos, 1)
End If

Next vl_pos
' 10 verminderen met de restwaarde van het bekomen getal gedeeld door 10
vl_isbn3 = 10 - (vl_isbn1 Mod 10)

If vl_isbn3 = vl_isbn2 Then
test_isbn = True
End If

End If
End Function

Visual Basic 6.0 na een upgrade van een windows 7 machine

Toen ik gisteren de windows 7 pc uitschakelde kreeg ik melding dat er tal van updates zouden plaatsvinden.
Deze morgen werden deze updates uitgevoerd en toen ik voor de dagtaak één van de visual basic6.0 projecten opende kreeg ik verschillende meldingen van niet geregistreerde objecten.

Ik opende enkele andere projecten en steevast met hetzelfde resultaat.
Dan de laptop maar eens ingeschakeld en daar openden de projecten, op een xp computer, wel nog.

Toen ik in de componenten van het project ging kijken zag ik dat het object mscomctl.oxc niet meer geladen was.

Ik opende een run box en voerde onderstaande in:

regsvr32 c:\windows\syswow64\MSCOMCTL.OCX

Nadien werkten al de projecten als voorheen, maar het was toch even schrikken.

Ik weet niet of dit ook voor zal doen op 32 bits pc’s die windows 7 draaien.

Inputmask in access

Soms is het wel eens noodzakelijk dat er aan een tekstveld een invoermasker (inputmask) wordt toegekend.
Dit zorgt ervoor dat de gebruiker de gegevens op de correcte wijze invoert.
Neem bvb de gegevens van de breedtegraad(Latitude), die dient als “99.999999” worden ingevoerd.
Lat en Lon gegevens kunnen immers gebruikt worden om op de website, in google maps een bepaald icoontje te plaatsen op de gewenste breedte- en lengtegraad.
Standaard wordt een inputmask niet naar de tabel geschreven, een waarde als 51.123456 zal dus als 51123456 opgeslagen worden. Uiteraard kunnen we hier niet mee akkoord gaan.
Plaats hiertoe in het form load event van het formulier onderstaande code:

txtLan.InputMask = “99.999999;0″
De ;0 zorgt ervoor dat het invoermasker als dusdanig zal worden opgeslagen.

Visual basic en .ico

Zelf een icoontje maken om te fungeren als icoon van de geschreven software is mooi.
Maar het icoontje moet van het juiste formaat zijn. Zo zal een transparent gif bestand dat je via het net tot een favicon.ico omtoverde niet goed zijn. Visual basic geeft de melding Invalid picture.

Wat moet je dan wel doen?
Exporteer je afbeelding naar een jpg afbeelding.
Ga het vervolgens het net op en zoek een favicon maker. Ik gebruik deze.

Sla het bestand op en selecteer vervolgens jou hoofdscherm van het programma.
Klik in het venster eigenschappen op icon en selecteer vervolgens het favicon.ico.

In de properties van het project (menu project – properties) selecteer je het 2de tabblad (make).
Kies bij Icon in het frame Application voor het icon dat op jou hoofdformulier staat.

Compileer en de executable heeft nu jouw icon als icoon voor het programma.

Access: Velden toe voegen en verwijderen in de master van een replicaset

Een bizar gebeuren bij access indien je in de master van een replicaset velden aan een tabel dient toe te voegen.
In de replica zelf gaat het sowieso niet om velden aan tabellen toe te voegen, maar en zo meldt de database ook als je de replicabewerking uitvoert, dat je enkel in de master tabellen kan aanpassen.

Access

Als ik echter de tabel die gewijzigd moet worden in ontwerpweergave open en vervolgens wens op te slaan krijg ik de melding: De bewerking is niet beschikbaar voor dit typeobject.
De help die hieruit opvraagbaar is slaat de bal ook redelijk mis.

Access

Maar in access kan je de structuur van een tabel ook wijzigen wanneer die tabel in gegevensmodus geopend is.
En zo lukte het mij wel.

Echter wanneer die kolom verwijderd dient te worden (ik deed het gewoon als test) dan krijg je dezelfde foutmeldingen.

Eigenschapsvenster niet zichtbaar in Access 2007 – 2010

Een collega kwam mij vragen hoe hij het eigenschapsvenster in access 2007 te zien kon krijgen.
Dit lukte hem onder geen enkel beding.
De toetsencombinatie alt+enter haalde niets uit en een klik op de knop ‘Property sheet’ in het ‘Design’ menu bracht evenmin het eigenschapsvenster naar voren.

Oplossing:
Druk alt F11 in om de vb editor te openen. Zorg ervoor dat het venster direct (immediat window) zichtbaar is. Indien dit niet het geval is, druk op Ctrl+G.

Tik volgende in:
CommandBars(“Property Sheet”).Enabled = True
en druk op enter. Vanaf nu zal het eigenschapsvenster wel getoond worden.

Visual Basic 6.0 compileren op windows 7 werkt niet op windows XP

Steeds, als ik een VB6 programma op een windows 7 computer compileerde, en het uitvoerbaar bestand vervolgens op een computer met een OS lager dan windows7 wenste uit te voeren kreeg ik de foutmelding:
Class does not support Automation or does not support expected interface.

Reden:
Microsoft ondersteunt niet langer het primaire interop-assembly voor ADO en niet langer Visual Basic 6.

Oplossing voor 64 bit computers
Download Msado60_Backcompat_i386.tlb naar een lokale map
Voor AMD64 computers
Download Msado60_Backcompat_x64.tlb naar een lokale map (ik plaatste deze op de c:\)
Voor IA64 (Intel) computers
Download Msado60_Backcompat_a64.tlb naar een lokale map

Registreer deze bestanden als volgt:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12 c:\msado60_Backcompat_i386.tlb
Voor AMD64
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12 c:\msado60_Backcompat_x64.tlb
Voor IA64
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12 c:\msado60_Backcompat_ia64.tlb

Het pad voor de regtlbv12.exe dient aangepast te worden als de.NET Framework 4.0 niet geïnstalleerd op het systeem. (Op mijn XP laptop stond dit bestand in Directory C:\Windows\Microsoft.NET\Framework\v2.0.5072). U dient immers hetzelfde te doen op de xp of lager OS als je de VB applicatie daar wenst te compileren/bewerken.

Vervolgens opent u de applicatie en ga naar references in het project menu.
Deselecteer de ADO referentie en maak een referentie naar Microsoft ActiveX-objecten 6.0 BackCompat.

Compileer opnieuw en de applicatie zal werken op de andere computer.

Google maps

Ik had zo een handige functie in een door mij geschreven programma, waarbij, na invoer van een locatie (verplaatsing) automatisch de reistijd en het aantal kilometer in de database werden weggeschreven.
Omdat ik binnenkort de installatie bij de klant moet gaan doen begon ik vandaag nog eens te testen.
1) Blijkt dat google de achterliggende html aangepast heeft.
Voorheen waren er 2 attributen, één voor de reistijd (met delimiter min.) en één voor de afstand op te halen met delimiter km.)
Dit was makkelijk werken natuurlijk.
Maar nu bestaat die eerste tag niet meer en komt alles als onderstaande in mijn uitgelezen string te staan na het uitlezen van de min. delimiter.

86,1 km,56
Niet zo leuk dat dit aangepast werd, maar bon een kleine aanpassing in de code en we kunnen zowel reistijd als afstand terug in de database gaan schrijven.
MAAR:
2) Blijkt de achterliggende html niet te stroken met wat uiteindelijk weergegeven wordt.

Google maps

Google maps

Software solutions and questions blog