У меня очень простое приложение, написанное в VBA (EXCEL). Это приложение получает некоторые входные данные и предоставляет файл *.pro
. (Это приложение получает входные данные и помещает их в *.pro
файл со своим собственным форматом.) Поля ввода - это числовые и текстовые данные, такие как:
CPE, W, W, 15,8, 16,5, 12, 23, 143,23 и так далее.
Когда я открываю вывод в Notepad++, я вижу что-то вроде этого:
Я пытаюсь написать функцию с С#.NET, которая обеспечивает аналогичный вывод. Поэтому я исследую файл vba и обнаружил, что он использует двоичный файл и записывает данные с помощью инструкции PUT:
Open FileName For Binary Access Read Write Lock Write As #fn
Put #fn, 1&, DummyName
Я пишу свой код на С# и пытаюсь сделать это с помощью BinaryWritter. Но вывод моего кода и приложения vba НЕ аналогичен. Обратите внимание, что файл *.pro может быть импортирован в некоторые сторонние программные продукты, такие как программное обеспечение CSi. И, как ясно, вывод моей функции НЕ является импортируемым. Вот часть кода, который я использую:
if (save.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (save.FileName.Length > 0)
using (BinaryWriter br = new BinaryWriter(File.Open(save.FileName, FileMode.Create)))
{
br.Write(dummy + dummy + dummy + dummy);
br.Write(7);
br.Write(5);
br.Write(1);
br.Write(dummy + dummy + dummy + dummy + dummy + dummy + "01234567");
br.Flush();
br.Close();
}
Есть ли способ узнать, какой алгоритм использовался для создания этого вывода? Или можно ли перевести этот вывод в читаемый формат?
И этот код для чтения файлов pro
Function FileReadOld() As Boolean
Dim i As Long
Dim j As Long
Dim fn As Long
Dim tmpBool As Boolean
Dim tmpFileName As String
Dim Dummy40 As String * 40
Dim tmpSingle As Single
FileReadOld = False
On Error GoTo OpenFileError
fn = FreeFile
Close #fn
Open FileName For Binary Access Read Write Lock Write As #fn
Get #fn, 1&, DummyName
Get #fn, , OldVersion
Get #fn, , OldUnits
Get #fn, , NumberOldSectionDatas
Get #fn, , DummyString1
If OldVersionRead = 6 And OldVersion <> 6 Then
msg = "The file named " & FileName & " is not recognized as a "
msg = msg & "PROPER Version 6 file. The section database file was NOT "
msg = msg & "read." & vbCrLf & vbCrLf
LogMsg = LogMsg & msg
Close #fn
Exit Function
End If
If OldVersionRead = 7 And OldVersion <> 7 Then
msg = "The file named " & FileName & " is not recognized as a "
msg = msg & "PROPER Version 7 file. The section database file was NOT "
msg = msg & "read." & vbCrLf & vbCrLf
LogMsg = LogMsg & msg
Close #fn
Exit Function
End If
Select Case OldUnits
Case 1
UnitsName = "Inches"
Case 2
UnitsName = "Feet"
Case 3
UnitsName = "Millimeters"
Case 4
UnitsName = "Meters"
Case 5
UnitsName = "Centimeters"
Case Else
msg = "The units specified in the file named " & FileName & " are "
msg = msg & "not recognized. The section database file was NOT "
msg = msg & "read." & vbCrLf & vbCrLf
LogMsg = LogMsg & msg
Close #fn
Exit Function
End Select
If NumberOldSectionDatas > 0 Then
ReDim SectionData(NumberOldSectionDatas)
End If
For i = 1 To NumberOldSectionDatas
Get #fn, , Dummy40
If OldVersionRead = 6 Then
SectionData(i).Name = UCase$(RTrim$(Left$(Dummy40, 18&)))
Else
SectionData(i).Name = UCase$(RTrim$(Left$(Dummy40, 36&)))
End If
SectionData(i).shapetype = UCase$(Left$(Right$(Dummy40, 4&), 2&))
Select Case SectionData(i).shapetype
Case "I ": SectionData(i).sh = SECTION_I
Case "W ": SectionData(i).sh = SECTION_I
Case "WW": SectionData(i).sh = SECTION_I
Case "C ": SectionData(i).sh = SECTION_CHANNEL
Case "T ": SectionData(i).sh = SECTION_T
Case "TW": SectionData(i).sh = SECTION_T
Case "L ": SectionData(i).sh = SECTION_ANGLE
Case "2L": SectionData(i).sh = SECTION_DBLANGLE
Case "B ": SectionData(i).sh = SECTION_BOX
Case "P ": SectionData(i).sh = SECTION_PIPE
Case "R ": SectionData(i).sh = SECTION_RECTANGULAR
Case "CR": SectionData(i).sh = SECTION_CIRCLE
Case "G ": SectionData(i).sh = SECTION_GENERAL
Case "SD": SectionData(i).sh = SECTION_GENERAL
End Select
'1: d, t3
Get #fn, , tmpSingle
Select Case SectionData(i).sh
Case SECTION_I, SECTION_CHANNEL, SECTION_T, SECTION_ANGLE, SECTION_DBLANGLE
SectionData(i).d = CDbl(tmpSingle)
Case SECTION_BOX, SECTION_RECTANGULAR, SECTION_GENERAL
SectionData(i).ht = CDbl(tmpSingle)
Case SECTION_PIPE, SECTION_CIRCLE
SectionData(i).od = CDbl(tmpSingle)
End Select
'2: bf, t2
Get #fn, , tmpSingle
Select Case SectionData(i).sh
Case SECTION_I, SECTION_CHANNEL, SECTION_T
SectionData(i).bf = CDbl(tmpSingle)
Case SECTION_ANGLE, SECTION_DBLANGLE, SECTION_BOX, SECTION_RECTANGULAR, SECTION_GENERAL
SectionData(i).b = CDbl(tmpSingle)
Case SECTION_PIPE, SECTION_CIRCLE
'not used
End Select
'3: tf
Get #fn, , tmpSingle
Select Case SectionData(i).sh
Case SECTION_I, SECTION_CHANNEL, SECTION_T
SectionData(i).bf = CDbl(tmpSingle)
Case SECTION_ANGLE, SECTION_DBLANGLE, SECTION_BOX, SECTION_RECTANGULAR, _
SECTION_GENERAL, SECTION_PIPE, SECTION_CIRCLE
'not used
End Select
'4: tw
Get #fn, , tmpSingle
Select Case SectionData(i).sh
Case SECTION_I, SECTION_CHANNEL, SECTION_T
SectionData(i).twsdb = CDbl(tmpSingle)
Case SECTION_ANGLE, SECTION_DBLANGLE, SECTION_PIPE
SectionData(i).t = CDbl(tmpSingle)
Case SECTION_BOX
SectionData(i).tdes = CDbl(tmpSingle)
Case SECTION_BOX, SECTION_RECTANGULAR, SECTION_GENERAL, SECTION_CIRCLE
'not used
End Select
'5: xk
Get #fn, , tmpSingle
Select Case SectionData(i).sh
Case SECTION_I, SECTION_CHANNEL, SECTION_T, SECTION_ANGLE, SECTION_DBLANGLE
SectionData(i).kdes = CDbl(tmpSingle)
Case SECTION_BOX, SECTION_RECTANGULAR, _
SECTION_GENERAL, SECTION_PIPE, SECTION_CIRCLE
'not used
End Select
'6: area
Get #fn, , tmpSingle
SectionData(i).a = CDbl(tmpSingle)
'7: torsion
Get #fn, , tmpSingle
SectionData(i).j = CDbl(tmpSingle)
'8: I33
Get #fn, , tmpSingle
SectionData(i).ix = CDbl(tmpSingle)
'9: I22
Get #fn, , tmpSingle
SectionData(i).iy = CDbl(tmpSingle)
'10: AS2
Get #fn, , tmpSingle
SectionData(i).asy = CDbl(tmpSingle)
'11: AS3
Get #fn, , tmpSingle
SectionData(i).asx = CDbl(tmpSingle)
'12: Z33
Get #fn, , tmpSingle
SectionData(i).zx = CDbl(tmpSingle)
'13: Z22
Get #fn, , tmpSingle
SectionData(i).zy = CDbl(tmpSingle)
'14: xb
Get #fn, , tmpSingle
SectionData(i).x = CDbl(tmpSingle)
'15: yb
Get #fn, , tmpSingle
SectionData(i).y = CDbl(tmpSingle)
'16: nothing
Get #fn, , tmpSingle
'17: dis
Get #fn, , tmpSingle
SectionData(i).dissdb = CDbl(tmpSingle)
'18: nothing
Get #fn, , tmpSingle
'19: t2b, nowhere to fill in this database
Get #fn, , tmpSingle
'SectionData(i).??? = CDbl(tmpSingle)
'20: tfb, nowhere to fill in this database
Get #fn, , tmpSingle
'SectionData(i).??? = CDbl(tmpSingle)
Next i
FileReadOld = True
Close #fn
Exit Function
OpenFileError:
msg = "Can not open the file named " & FileName & "! It may be in use "
msg = msg & "by another program. The section database file was NOT "
msg = msg & "read." & vbCrLf & vbCrLf
LogMsg = LogMsg & msg
Close #fn
Exit Function
End Function
Put
в VBA иногда записывает различные дескрипторы и длины полей вместе с данными. Эта дополнительная информация зависит от типа данных записываемой переменной (например,DummyName
в вашем случае). Эта страница на MSDN содержит подробную информацию.