vba text compression
Option Explicit #If VBA7 Then Private Declare PtrSafe Function Compress& Lib "cabinet" (ByVal hCompressor&, ByVal pUncompressedData&, ByVal sizeUncompressedData&, ByVal pCompressedDataBuffer&, ByVal sizeCompressedBuffer&, bytesOut&) Private Declare PtrSafe Function Decompress& Lib "cabinet" (ByVal hCompressor&, ByVal pCompressedData&, ByVal sizeCompressedData&, ByVal pUncompressedDataBuffer&, ByVal sizeOfUncompressedBuffer&, bytesOut&) Private Declare PtrSafe Function CreateCompressor& Lib "cabinet" (ByVal CompressAlgorithm&, ByVal pAllocationRoutines&, hCompressor&) Private Declare PtrSafe Function CreateDecompressor& Lib "cabinet" (ByVal CompressAlgorithm&, ByVal pAllocationRoutines&, hDecompressor&) Private Declare PtrSafe Function CloseCompressor& Lib "cabinet" (ByVal hCompressor&) Private Declare PtrSafe Function CloseDecompressor& Lib "cabinet" (ByVal hDecompressor&) #Else Private Declare Function Compress& Lib "cabinet" (ByVal hCompressor&, ByVal pUncompressedData&, ByVal sizeUncompressedData&, ByVal pCompressedDataBuffer&, ByVal sizeCompressedBuffer&, bytesOut&) Private Declare Function Decompress& Lib "cabinet" (ByVal hCompressor&, ByVal pCompressedData&, ByVal sizeCompressedData&, ByVal pUncompressedDataBuffer&, ByVal sizeOfUncompressedBuffer&, bytesOut&) Private Declare Function CreateCompressor& Lib "cabinet" (ByVal CompressAlgorithm&, ByVal pAllocationRoutines&, hCompressor&) Private Declare Function CreateDecompressor& Lib "cabinet" (ByVal CompressAlgorithm&, ByVal pAllocationRoutines&, hDecompressor&) Private Declare Function CloseCompressor& Lib "cabinet" (ByVal hCompressor&) Private Declare Function CloseDecompressor& Lib "cabinet" (ByVal hDecompressor&) #End If Function CompressString$(s$, Optional algorithm& = 5) Dim h&, max&, bytesOut&, b$ If Len(s) Then If CreateCompressor(algorithm, 0&, h) Then max = LenB(s): b = Space$(max) If Compress(h, StrPtr(s), max, StrPtr(b), max, bytesOut) Then If bytesOut Then CompressString = Left$(b, bytesOut \ 2) End If CloseCompressor h End If End If End Function Function DecompressString$(s$, Optional algorithm& = 5) Dim h&, bytesOut&, b$ If Len(s) Then If CreateDecompressor(algorithm, 0&, h) Then b = Space$(LenB(s) * 50) If Decompress(h, StrPtr(s), LenB(s), StrPtr(b), LenB(b), bytesOut) Then If bytesOut Then DecompressString = Left$(b, bytesOut \ 2) End If CloseDecompressor h End If End If End Function '------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Dim GreenEggs$, Tiny$, Roundtrip$ GreenEggs = "I do not like them in a box. I do not like them with a fox. I will not eat them in a house. I do not like them with a mouse. I do not like them here or there. I do not like them ANYWHERE!" Tiny = CompressString(GreenEggs) Roundtrip = DecompressString(Tiny) MsgBox Len(GreenEggs) '<--displays: 187 MsgBox Len(Tiny) '<--displays: 73 MsgBox Len(Roundtrip) '<--displays: 187 Debug.Print Roundtrip '<--displays Dr. Seus's breakfast problem 'Note: Tiny (the compressed string) can be written to disk and decompressed ' at a later date. 'Note: These functions use the Win32 Compression API, which is bundled with 'Windows since Windows 8. These function will not work on Windows 7 and earlier. 'Note: These functons default to using Algorithm #5: LZMS. The functions can ' optionally be directed to use the other supported MS API ' compression algorithms: ' MSZIP: 2 ' XPRESS: 3 ' XPRESS_HUFF: 4 ' LZMS: 5 'Note: There is no Algorithm #1 included in the API. 'Note: The default LZMS compression algorithm seems to compress the best. 'Reference: ' https://docs.microsoft.com/en-us/windows/win32/api/_cmpapi/