This macro will determine the 'MinimalVersionToRead' of the selected CatDocs and display them in a sortable listview.
You start the macro by either dragging directories/files from explorer on to the icon
or, if the program window has already been opened, by dropping items onto the form.
Batch mode should work, although the macro was not conceived to.
The program evaluates the parameters passed on startup as well as the names of the dropped files/directories.
All files ending with '.CAT*' will be inspected. When dropping file/directory names onto the program icon please keep in mind, that the routine expects a blank between the different names. Blanks within the file names/paths will lead to errors and cause the macro to misinterpret the file names. When dropping files/dirs onto the opened form, blanks have no adverse effect.
Release Notes Version 1.5:
Version 1.2 had no sorting capabilities.
Pre-2002 created Catia files caused an error.
Reason: The step from V5R7/8 to V5R8/9 (2002) obviously came with an additional change in the file format. Pre-2002 Catia documents simply do not state the 'MinVersionToRead' in their data and therefor cannot be found. Both issues were addressed in V1.5.
Instead of a simple listbox now a sortable ListView is used.
Release Notes Version 1.6:
Added the column 'Last Version Saved'.
Reason: A Catia document showing a MinimalversionTo Read of V5R14(eg) may have been created using V5R15SP20.
Version V5R14SP0 would not be able to handle that file.
Program execution:
The makro reads a chunk of the file and searches for 'CATSummaryInformation' and, if found, for 'MinimalVersionToRead'.
If 'CATSummaryInformation' was not found within the first chunk of data, the next chunk will be inspected. If need be, the entire file will be searched.
Code snippet to find 'MinimalVersionToRead':
'---------------------------------------------------------------------------------------
' Procedure : GetCatiaRelease
' Author : jherzog
' Date : 10.08.2015
' Time : 20:00
' Languages : VB6 Pro SP6
' V5-Release: V5R19/21
' Purpose : Find 'MinimalVersionToRead' - entry
' Parms : strFileFullPath: fully qualified filename (= path + file)
' Ret. Value: - Found entries are added to list1 listbox
'
' Syntax : GetCatiaRelease strFN
'
' Prereqs : the name of a Catia-file
' Remarks : If 'lChunkSize' is too small on the first pass, it is increased.
' : If EOF is reached and Version/Release is still not found
' : 'VERSION NOT FOUND' is added to list
'---------------------------------------------------------------------------------------
' V1.6:
' - Spalte 'Last Version Saved' hinzu;
' - CATVERSION_Type, lsv, fsv hinzu;
' - Auswertung von SP, HotFix, CATBuildLevel hinzu;
' - Sprungmarke auf 'CATSummaryInformation' oder 'MinimalVersionToRead' erweitert
'
'
'---------------------------------------------------------------------------------------
Sub GetCatiaRelease(strFileFullPath As String)
Dim lFSize As Long 'file size
Dim lStart As Long 'start position of data
Dim lPos As Long
Dim lFilePointer As Long 'starting pos for setfilepointer
Dim strTmp As String 'string read from file holding file's data
Dim strMinVersionRead As String
Dim strLastVersion As String 'includes version, release, servicepack, hotfix
Dim strBuildLevel As String 'date and time
Dim strFileName As String 'file name
Dim strHeader As String 'first 16 bytes of files
Dim strMsg As String
Const lChunkMid As Long = &H100000 '1Mb
Const lChunkSmall As Long = &H4000 '16k
Const lChunkBig As Long = &H1000000 '16Mb
Dim lChunkSize As Long 'chunk size
Dim bEOF As Boolean 'eof-flag
Dim iDelta As Integer 'lfilepointer displacement
Dim lsv As CATVERSION_Type 'last saved version
Dim fsv As CATVERSION_Type 'first streamed
On Error GoTo GetCatiaRelease_Error
strFileName = Right$(strFileFullPath, _
Len(strFileFullPath) - InStrRev(strFileFullPath, "\")) 'strip path
lFSize = FileLen(strFileFullPath) 'get file size
'read header; read last chunk and search for MinimalVersionToRead
strHeader = ReadChunkToString(strFileFullPath, 16, 0&, bEOF) 'read header
If Left$(strHeader, 7) <> "V5_CFV2" Then 'check for catia file sig
If strHeader = "ERROR" Then 'eg. open file error
strMsg = "FILE READ ERROR"
Else
strMsg = "NOT A CATIA DOC" 'ending begins with 'CAT', but no sig found
End If
AddLVEntry strFileName, strMsg, "N/A" 'add to list
Exit Sub 'if not catia file, skip read
End If
lChunkSize = lChunkMid
lFilePointer = lFSize - lChunkSize 'set file pointer to last chunk
If lFilePointer < 0 Then lFilePointer = 0 'no negative pointers
Do 'read file til release or eof found
strTmp = ReadChunkToString(strFileFullPath, lChunkSize, lFilePointer, bEOF)
If InStr(strTmp, "CATSummaryInformation") Then
lStart = InStr(strTmp, "CATSummaryInformation") 'find summary info
Else
If InStr(strTmp, "MinimalVersionToRead") Then
lStart = InStr(strTmp, "MinimalVersionToRead") 'find min version2read
iDelta = 300
End If
End If
If lStart > 0 Then 'string found
strTmp = ReadChunkToString(strFileFullPath, lChunkSmall, lFilePointer + lStart - iDelta, bEOF)
lPos = InStr(strTmp, "LastSaveVersion") 'find entry
If lPos > 0 Then 'found
lPos = InStr(lPos, strTmp, "<Version>") 'find version
If lPos > 0 Then 'r10 uses different format; skip
lsv.Version = Mid$(strTmp, lPos + Len("<Version>"), 1) 'works until version 10
lPos = InStr(lPos, strTmp, "<Release>") 'find release
lsv.Release = Mid$(strTmp, lPos + Len("<Release>"), _
InStr(lPos, strTmp, "/<Release>") - Len("<Release>") - lPos)
lPos = InStr(lPos, strTmp, "<ServicePack>") 'find ServicePack
lsv.Servicepack = Mid$(strTmp, lPos + Len("<ServicePack>"), _
InStr(lPos, strTmp, "/<ServicePack>") - Len("<ServicePack>") - lPos)
lPos = InStr(lPos, strTmp, "<BuildDate>") 'find BuildDate
lsv.BuildDate = Mid$(strTmp, lPos + Len("<BuildDate>"), _
InStr(lPos, strTmp, "/<BuildDate>") - Len("<BuildDate>") - lPos)
lPos = InStr(lPos, strTmp, "<HotFix>") 'find HotFix
If lPos > 0 Then
lsv.Hotfix = Mid$(strTmp, lPos + Len("<HotFix>"), _
InStr(lPos, strTmp, "/<HotFix>") - Len("<HotFix>") - lPos)
Else
lsv.Hotfix = " n/a"
End If
strLastVersion = "V" & lsv.Version & " R" & lsv.Release & " SP" & lsv.Servicepack & " HF" & lsv.Hotfix
Else
strLastVersion = "N/A"
End If
Else
strLastVersion = "N/A"
End If
If InStr(strTmp, "MinimalVersionToRead") Then 'find min version2read
lPos = InStr(strTmp, "CATIA") 'find entry
strMinVersionRead = Mid$(strTmp, lPos, 10) 'read entry
'if release is pre R10(one digit; insert '0' for sorting
If Asc(Right$(strMinVersionRead, 1)) < &H30 Or _
Asc(Right$(strMinVersionRead, 1)) > &H39 Then 'not a number; shorten entry
strMinVersionRead = Left$(strMinVersionRead, 8) _
& "0" & Mid$(strMinVersionRead, 9, 1) 'CATIAV5R9 zB
End If
Else 'is the build level there?
If InStr(strTmp, "CATBuildLevel") Then
lPos = InStr(strTmp, "CATBuildLevel") 'find build level
strBuildLevel = "B/L: " & Mid$(strTmp, lPos + Len("CATBuildLevel") + 8, 10) _
& " " & Mid$(strTmp, lPos + Len("CATBuildLevel") + 19, 2) _
& ":" & Mid$(strTmp, lPos + Len("CATBuildLevel") + 22, 2)
strMinVersionRead = strBuildLevel 'show build level instead of min version
Else
strMinVersionRead = "VERSION NOT FOUND"
End If
End If
AddLVEntry strFileName, strMinVersionRead, strLastVersion 'add to list
Exit Do 'quit
Else 'else increase chunk size
lChunkSize = lChunkBig
End If
If bEOF = True Then 'if eof then
AddLVEntry strFileName, "VERSION NOT FOUND", "N/A" 'add message to list
Exit Do 'quit
End If
strTmp = "" 'free memory
lFilePointer = lFilePointer - lChunkSize + Len("MinimalVersionToRead")
If lFilePointer < 0 Then lFilePointer = 0 'no negative pointers allowed
Loop
strTmp = "" 'free memory
Exit Sub
'---------------------------------------------------------------------------------------
GetCatiaRelease_Error:
Dim errMsg As String
Dim errRet As VbMsgBoxResult
Select Case Err.Number
Case 6 'überlauf/overflow;
' errMsg = Err.Number & ": " & Err.Description & " in procedure GetCatiaRelease" _
' & vbCr & strFileFullPath
' errRet = MsgBox(errMsg, vbOKOnly, "GetCatiaRelease")
AddLVEntry strFileFullPath, "OVERFLOW", "N/A"
' Case -2147467259
Case Else
errMsg = Err.Number & ": " & Err.Description & " in procedure GetCatiaRelease"
errRet = MsgBox(errMsg, vbOKOnly, "GetCatiaRelease")
End Select
'Resume Next 'fall thru to quit sub
'---------------------------------------------------------------------------------------
End Sub
'---------------------------------------------------------------------------------------
' Procedure : ReadChunkToString
' Author : jherzog
' Date : 10.08.2015
' Time : 20:00
' Languages : VB6 Pro SP6
' V5-Release: V5R19/21
' Purpose : Read chunk of a file and assign to a string
' Parms : strFN: Full path + name of file to read
' : lChunk: chunk size
' : lFPtr: file read pointer offset
' Ret. Value: the string holding the file's contents or "" or "ERROR"(file open error)
'
' Syntax : strTmp = ReadChunkToString(strFileFullPath, lChunkSize, lFilePointer, bEOF)
'
' Prereqs : an existing file
' Remarks :
'---------------------------------------------------------------------------------------
'
Private Function ReadChunkToString(strFN As String, lChunk As Long, lFPtr As Long, bEOF As Boolean) As String
Dim lBytesRead As Long 'number of bytes read
Dim ret As Long 'return value from ReadFile; 0 or 1
Dim hwndTextFile As Long 'handle to opened file
Dim lFSize As Long 'file size
Dim TempStr As String 'string to hold data
On Error GoTo ReadChunkToString_Error
'open the file
hwndTextFile = CreateFile(strFN, GENERIC_READ, 0, 0, _
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS Or FILE_ATTRIBUTE_NORMAL, 0)
If hwndTextFile <> INVALID_HANDLE_VALUE Then 'if we have a valid handle
ret = SetFilePointer(hwndTextFile, lFPtr, 0&, FILE_BEGIN)
TempStr = String$(lChunk, Chr$(0)) 'init placeholder for data string
ret = ReadFileByNum(hwndTextFile, TempStr, _
lChunk, lBytesRead, 0) 'read file into string
If ret <> 0 Then 'read was successful
ReadChunkToString = TempStr
TempStr = ""
End If
If lChunk <> lBytesRead And ret <> 0 Then
bEOF = True
End If
CloseHandle hwndTextFile 'close handle
Exit Function 'and quit
End If
'---------------------------------------------------------------------------------------
'fall through to error message
ReadChunkToString = "ERROR" 'tempstr is empty; fileopen error?
Exit Function
'---------------------------------------------------------------------------------------
ReadChunkToString_Error:
Dim errMsg As String
Dim errRet As VbMsgBoxResult
Select Case Err.Number
' Case 438
' Case -2147467259
Case Else
errMsg = Err.Number & ": " & Err.Description & " in procedure ReadChunkToString"
errRet = MsgBox(errMsg, vbOKOnly, "ReadChunkToString")
End Select
ReadChunkToString = "ERROR"
'Resume Next 'fall thru to quit sub
'---------------------------------------------------------------------------------------
End Function
Miscellaneous:
A word on the MinimalVersionToRead entries:
Entry: | Meaning: |
CATIAV5R17 |
Catia-documents: CATDrawing, CATPart, CATProduct, as well as CATShape, Catalog, CATMaterial, CATSystem, ... |
Version Not Found | Catia - Doc with 'V5_CFV2' - header, but w/o 'MinVersionToRead' - entry (pre-2002) |
Not a Catia Document | All other '.CAT's, but w/o 'V5_CFV2' header, eg. '.catscript' |
Not a Catia File | File ending <> 'CAT*' |
Error | File could not be opened; read error. File may already be open. |
Overflow | This error has been taken care of and should not appear. Occurred with pre-2002 files. |