Using the free zip library in VBA

Software

In a previous post I briefly explained how you can compile the free zlib library with Visual 2013 Studio and produce a 32 and a 64 bits dll that you can then use in VBA (Word, Excel, Access, etc…). If you follow this link to the article, you can even download the binaries I baked.

However, to use these dlls in a real world project, we need to wrap them in some 32/64 bits VBA code.
Inspired by samples I found on the web, here a quickly reusable module for your VBA projects.
Look at the TestXXXX procedures (change the pathes and filenames, of course, and execute them in the immediate window) for some samples.

Enjoy!

 

 

4 comments

How to get the same result in VBA and in PHP computing a CCITT CRC checksum

Internet, Microsoft, Software

I was working last week on a Microsoft Access application and I needed to get some data from a webserver running Apache/PHP. Exchanging data with the server was easy, the WinHTTP and XML ActiveX library components are really cool and easy to use for that. But then I came unto some unexpected trouble when I tried to use a CRC check on both the VBA and PHP side to quickly add some integrity checking on the exchanged data.

I already had a VBA routine computing a CRC checksum, but had none on the PHP side. So I thought “google it up”, pick the first CRC checksum routine that comes up and use it, easy. By the way, if you want to refresh your neurons about the CRC stuff, you can read more about that in wikipedia.

To make a long story short, there are many algorithms out there, for VBA and PHP, and to find two that go well along and yield the same result, it takes some time and tries.

So, here are the two ones I now use. Enjoy !

Note: replace “&” with “&” in the code, it’s a wordpress problem, sorry.

VBA:

'Compute a CRC for a string (16bits CRC, CCITT inverted)
'Original source: 'http://www.xtremevbtalk.com/showthread.php?t=318655
'Added string param instead od byte array, ErrHandler and second optional parameter InputCrc
Private Function CRC16_2(ByVal psData As String, Optional ByVal plInitCrc As Variant) As Long
Const CRC_POLYNOM As Long = &H8408&
Const CRC_PRESET As Long = &HFFFF&
Dim crc As Long, i As Long, j As Long
Dim Buffer() As Byte

On Error GoTo ErrHandler

Buffer = StrConv(psData, vbFromUnicode)

If IsMissing(plInitCrc) Then
crc = CRC_PRESET 'unsigned internal CRC = CRC_PRESET
Else
crc = plInitCrc
End If
For i = 0 To UBound(Buffer) 'for(i=0; i < cnt; i++)
crc = crc Xor Buffer(i) 'crc ^= Buffer[i]
For j = 0 To 7 'for(j=0; j<8;j++)
If (crc And 1) Then 'if(crc & 0x0001)
crc = (crc \ 2) Xor CRC_POLYNOM 'crc=(crc>>1)^CRC_POLYNOM;
Else
crc = (crc \ 2) 'crc=(crc>>1)
End If
Next j
Next i
CRC16_2 = crc
ErrHandler:
End Function

And in PHP:

// CCITT, X24
define('CRC16POLYI',0x8408);

/*
* Source: https://forums.digitalpoint.com/threads/php-define-function-calculate-crc-16-ccitt.2584389/
* Note: no second parameter here as on the VBA version
*/
function CRC16Inverse($buffer) {
$result = 0xFFFF;
if ( ($length = strlen($buffer)) > 0) {
for ($offset = 0; $offset < $length; $offset++) {
$result ^= ord($buffer[$offset]);
for ($bitwise = 0; $bitwise < 8; $bitwise++) {
$lowBit = $result & 0x0001;
$result >>= 1;
if ($lowBit) {
$result ^= CRC16POLYI;
}
}
}
}
return $result;
}
0 comments

8 business books for solopreneurs

Books

In 20 years of “solo” business, ie being a self-employed gullible working bee, I’ve learned the hard way to change, refocus and shape my lifestyle. I’m on new pathes now,

To save yourself some years of torture, if you’re going solo and you didn’t happen to stumble upon one of my selected business books, then may I strongly suggest you consider reading them ?

Be ready, and happy, to change.

2 comments

5 Sci-Fi books I enjoyed on my kindle

Books, Sci-Fi

They’re all by Richard Philips. Well, the second one is still in the makings, so I already pre-ordered my edition on amazon.com.

Look for the link on the home page, in the upper right corner, or click here.

More Sci-Fi book recomendations coming. And books in other categories too.

Stay tuned, and enjoy !

0 comments

Play blueray DVDs with VLC in Windows 8.1

Entertainment, Hardware

Call it a nightmare. You just bought the full “Prison Break” serie blueray DVDs. Neither PowerDVD, nor Windows media player or VLC can read them. It’s a shame. But VLC rules. Simply follow the instructions here: http://vlc-bluray.whoknowsmy.name/. Don’t ask me if it’s legal although. I did pay for my player, and for my DVDs, so I don’t see any reasons it wouldn’t be. Enjoy !

0 comments

Share the Clipboard with VBA and the Windows API

Microsoft, Software

Accessing the clipboard in Windows becomes quite tricky in VBA, particularly if you have to stay 32 and 64 bits compatible.

Here’s my compilation of portable routines, inspired by MSDN, Internet scraping and good sense.

First the Declares section (I know, it pours out of the frame on the right, just select and copy the text):

Then the VBA code:

Update: just a quick sample (Access VBA):

There’s an Access 2016 demo database (on devinfo.net), open it, go to the VBA editor (ALT+F11), go to the debug Windows (CTRL+G), type “Test” (without the quotes of course) and hit ENTER; any text in the clipboard will be displayed in the debug window.

Enjoy.

6 comments

Microsoft Access Databases ADO connection strings for 32/64 bits

Microsoft, Software

If you try to open a connection to an Access database via ADO, you’ll have to use a different provider, whether you’re coding for 32 or 64 bits environments.

Here’s a utility function I use for that (updated 25.02.2014):

Of course you have to have the correct jet engine files installed on the target computer, but just a warning here: you’ll find quite a few links to download the Access 2010 database engine redistributable package, but if you’re using Office 2013 and you install this redistributable package, as soon as you’ll start an Office application, the repair feature of the Office installer will trigger.

And the GetFileExt() function:

0 comments

Compiling the zlib compression library with Visual Studio 2013

Software

I you need zip compression in your development project, the zlib library is a good and free solution.
There’s however a bit of googling necessary to achieve a successful compilation with VS2013, especially for generating the 32 bits version of the library.
As I just needed it for some VB/VBA integration, I had to sort out a lot of outdated and not really useful information, for a simple solution, after all.
So here’s my receipe which will help you save some time, I hope, if you’re on the same track.

Update #2, 11/12/2013, here are my compiled binaries, zlibwapi32.dll and zlib64.dll in this zip archive, MD5: eb8932beb0360b42c6cdd1ccd79745ad

Download the library source code here: http://www.zlib.net, then:

  1. Uncompress the archive (in my case zlib-1.2.8.zip), you’ll find a zlibvc.sln file in the contribvstudiovc11 subfolder, that you can open with vs2013 (let it do its conversion stuff);
  2. The annoying part comes if you’re compiling against a Win32 target, because you then have to specify an additional linker command line switch /SAFESEH:NO. Right-click the zlibvc project and open its property pages:
  3. vs2013compile
  4. Do the same for the testzlib project
  5. Give it a go.

For the Win64 version, the linker switch does not apply, just go directly to the build process.

Note that you’ll end up with a zlibwapi.dll file that you can use with your vb/vba projects.
I did compile 32 and 64 bits versions of the library, and I renamed them zlibwapi32.dll and zlibwapi64.dll to avoid confusion; here are the declares for the 32 bits version:
(Updated 11/12/2013)

It’s then quite easy to figure out how to use the functions in your C/C++/VB/Whatever projects, samples are included with the library, but for VB/VBA, here is an excellent introduction from Mike D Sutton: http://edais.mvps.org/Tutorials/ZLib/index.html .
Happy zipping!

5 comments

Shell Hell for VBA 64 bits

Microsoft, Non classé, Software

One of the useful uses of the Windows API, back in the old days of 32 bits programming, was to use the shell’s standard dialogs for browsing for a folder or picking a file. VB/VBA didn’t have a way to do that, whereas today, modern VB, I mean VBA7 of course (today’s “Visual Basic” denomination being attributed to the VB.NET treacherous brother), has beautiful means to do that; just install some megabytes of Office and there you go.

So there is the 32 bits code I use for browsing for a folder:

Now, I couldn’t find a way to make this work in 64 bits, and frankly, Internet has a lot of bugged code for you to try to. Many claim to have something working, I couldn’t find the correct declarations and calls to avoid GPFing. The crashes occur when invoking SHGetPathFromIDList.

Here’s how to do it in modern VBA (got it on developpez.net), and in classic VB5/VB6; note that we don’t need a port anymore as there’s is no 64 bits VB/VBA, thanks Microsoft, we always knew you wouldn’t let us down:

So, SHxxx or Shell functions are indeed hell-ish! As another example, it took me quite some time to port to 64 bits the damned SHGetSpecialFolderLocation function.

Again, hard to find any truly working code on the net.
So, let’s go for mine if you don’t mind. Here’s how I declare it:

And there’s how I make it work without crashing:

Hey, hope I spared you some head banging guys !

Time to post a decent comment (“Woaw”, “You suck” are ok too), fellow VB/A developpers.
I need to be a bit encouraged; then I’ll post my solution for another piece, the API way of using the clipboard (getdata/setdata with text), 32 and 64 bits compatible, a working one again.

Cheers 😉

6 comments

Les méandres de TCP/IP (2002)

Internet

Introduction

TCP et IP ont été développé par l’agence de projets de recherche avancée (DARPA, Defense Advanced Research Project Agency) du département de la défense américaine (DOD), en 1969, dans le cadre du projet de recherche ARPANET (Advanced Research Project Agency Network) visant à connecter des réseaux conçus par différents fournisseurs en un super-réseau, le “réseau des réseaux”: internet.

Remarque: le mot internet (avec i minuscule) fait référence à de multiples réseaux TCP/IP interconnectés avec des “routeurs”. Internet (avec I majuscule) fait référence au réseau mondial public Internet. Un intranet est un réseau internet privé. Et enfin, un extranet est un réseau intranet privé et protégé, accessible depuis Internet.

TCP/IP

Le succès initial de TCP/IP vient du fait qu’il fournit des services de base essentiels (tranfert de fichiers (FTP), email (SMTP, POP, IMAP), contrôle à distance (TELNET), …) et qu’il peut être utilisé par plusieurs ordinateurs sur le même réseau local, tout en cohabitant avec les protocoles de communication déjà en place.

Le composant IP est chargé du routage de l’information, du poste de travail d’un réseau local à un réseau d’entreprise, en passant par un réseau régional, et finalement jusqu’au réseau global Internet. IP cherche la meilleure route utilisable pour communiquer, d’un point à un autre.
Comme les réseaux physiques sont sujets à des pannes inévitables, le DOD a conçu TCP/IP afin qu’il soit stable. Lorsqu’un chemin de communication est obstrué (ou surchargé), IP se charge de trouver une route alternative.

Cette conception permet la construction de très larges réseaux nécessitant une administration centrale minimale. L’inconvénient majeur étant que les problèmes réseaux sont diagnostiqués plus difficilement car moins visibles.

Comme nombres d’autres protocoles, TCP/IP est composé de couches.

  • IP – est responsable du déplacement des paquets de données, de point à point. IP transfère chaque paquet à une adresse de destination encodée sur 4 octets (adresse IP). Les autorités Internet assignent des plages de numéros à différentes organisations. Ces organisations assignent à leur tour leurs numéros à des entités ayant besoin d’une présence internet. IP fonctionne sur des passerelles qui déplacent les données de réseau local à réseau d’entreprise, puis de réseau régional au réseau global Internet: les routeurs.
  • TCP – est responsable de vérifier la transmission correcte des données, du client au serveur. TCP se charge de découper le message d’origine en paquets de données appelés datagrammes, puis de les réassembler à l’arrivée (dans le bon ordre).
    Les données peuvent être perdues dans un réseau intermédiaire. TCP ajoute la possibilité de détecter les erreurs ou les données perdues et de les retransmettre jusqu’à ce quelle soient correctement et complètement reçues.
  • Sockets – est le nom donné aux librairies de programmes qui permettent d’utiliser TCP/IP sur la plupart des systèmes.

Adresse IP

Une adresse IP est un numéro codé sur 32 bits (soit 4 octets), conventionellement représenté par quatre chiffres décimaux séparés par un point. Par exemple: 194.38.3.24 est une adresse IP. Cette représentation est appelée notation w.x.y.z (notation décimal pointée ou dotted decimal notation, termes que vous rencontrerez également dans la littérature).

Une adresse IP est constituée de deux parties : le Network ID (identifiant de réseau, ou adresse de réseau) et le host ID (identifiant de noeud, ou adresse de noeud).

  • Network ID – identifie les ordinateurs connectés au même brin de réseau physique délimité par des routeurs IP. Les Network IDs sont unique sur internet.
  • Host ID – identifie un ordinateur, un routeur ou un autre périphérique (par exemple une imprimante) connecté à un réseau. Chaque Host ID est unique, pour un Network ID donné.

Classes d’adresses

Les classes d’adresses IP accomodent les différentes tailles et configurations de réseaux TCP/IP (rappelez-vous bien que TCP/IP est un monde de réseaux divers interconnectés, il y a un nombre gigantesque combinaisons possibles).

Il y a 5 classes d’adresses. Windows NT supporte les classe A, B et C.

La classe A

Les adresses de classe A sont assignées à des réseaux disposant d’un nombre très large de machines connectées. Avec des adresses de cette classe, 126 réseaux peuvent être définis et 16’777’214 machines.

La classe B

Pour les moyens et grands réseaux. Avec des adresses de cette classe, 16’384 réseaux peuvent être définis et 65’534 machines.

La classe C

Pour les petits réseaux (typiquement les réseaux de PME). Avec des adresses de cette classe, 2’097’152 réseaux peuvent être définis avec 254 machines par réseau.

Résumé

Classe Valeur pour w Portion Netword ID Portion Host ID réseaux Machines
A 1-126 w x.y.z 126 16’777’214
B 128-191 w.x y.z 16’384 65’534
C 192-223 w.x.y z 2’097’152 254
Classe 1er Network ID Dernier Network ID
A 1.0.0.0 126.0.0.0
B 128.0.0.0 191.255.0.0
C 192.0.0.0 223.255.255.0

Remarques:
1. Les NetworkID spécifiés ci-dessus ne sont pas des adresses IP.
2. L’adresse de classe A 127.x.y.z est utilisée pour des test de bouclage locaux et pour la communication interprocessus sur la machine locale.
127.0.0.1: Cette adresse virtuelle est disponible sur toute plateforme Windows où TCP/IP est installé. Les serveurs web installés localement sur la machine, répondrons à cette adresse par défaut dont l’url correspondante est: http://localhost.

Sous-réseaux et masques de sous-réseau

Si vous trouviez ça compliqué jusqu’ici, alors accrochez-vous, parceque la suite c’est une vrai cuisine où il y a beaucoup de plats qui mijotent en même temps. C’est d’ailleurs le dernier point sur TCP/IP que j’aborde ici et j’en fais un survol vraiement très, très sommaire.

C’est parti.

On voit que la classe A permet d’avoir physiquement plus de 16 millions de machines connectées au même brin de réseau qui est délimité par des routeurs. C’est un chiffre énorme et qui de toute évidence pose un problème de gestion du parc (imaginez vous le temps que ça prendrait, rien qu’à afficher les machines dans votre voisinage réseau).

On a donc trouvé un moyen de délimiter des sous-ensembles du réseau que forme un classe d’adresse, en ajoutant ce que l’on pourrait qualifier de sélecteur: le masque de sous-réseau.

Masque de sous-réseau

Une adresse IP ne suffit donc pas à identifier une machine sur un réseau TCP/IP. Il faut connaître encore son masque de sous-réseau. Ce masque est un nombre, codé sur 32 bits, comme l’est également l’adresse IP.
En combinant ce masque avec l’adresse IP, par l’opérateur logique ET, bit à bit, on peu identifier la partie réelle représentant le Network ID de l’adresse IP, ainsi que la partie représentant le Host ID. La recette prends des pages, alors oublions-là et concentrons nous sur ce qu’il reste d’essentiel à savoir sur le masque de sous-réseau.

Le masque de sous-réseau est représenté en notation w.x.y.z.

Rien ne nous oblige à diviser un réseau TCP/IP en sous-réseaux. Lorsqu’un réseau TCP/IP n’est pas sub-divisé, on doit tout de même spécifier un masque de sous-réseau. Ce sont les masques de sous-réseaux par défaut, que je récapitule dans la table suivante:

Classe Masque de sous-réseau (par défaut)
A 255.0.0.0
B 255.255.0.0
C 255.255.255.0

C’est l’administrateur de votre réseau ou votre fournisseur d’accès internet qui fixe ces paramètres.

(Article publié en 2002 à l’origine)

0 comments