Reading Excel in BIFF format

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Reading Excel in BIFF format

Сообщение Чудик » 24.01.2005 (Пн) 0:06

Вопрос:
Как считать данные из определенной ячейки рабочей книги Excel, открытой как двоичный файл (формат BIFF)?
Век живи - век учись!
www.detal-plast.narod.ru

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 24.01.2005 (Пн) 11:18

Код: Выделить всё
Public Function WriteValue(ValueType As ValueTypes, CellFontUsed As CellFont, Alignment As CellAlignment, HiddenLocked As CellHiddenLocked, lrow As Long, lcol As Long, value As Variant, Optional CellFormat As Long = 0) As Integer

On Error GoTo Write_Error

'the row and column values are written to the excel file as
'unsigned integers. Therefore, must convert the longs to integer.
   
    If lrow > 32767 Then
       Row% = CInt(lrow - 65536)
    Else
       Row% = CInt(lrow) - 1    'rows/cols in Excel binary file are zero based
    End If
       
    If lcol > 32767 Then
       col% = CInt(lcol - 65536)
    Else
       col% = CInt(lcol) - 1    'rows/cols in Excel binary file are zero based
    End If

   
    Select Case ValueType
      Case ValueTypes.xlsinteger
         Dim INTEGER_RECORD As tInteger
         With INTEGER_RECORD
           .opcode = 2
           .Length = 9
           .Row = Row%
           .col = col%
           .rgbAttr1 = CByte(HiddenLocked)
           .rgbAttr2 = CByte(CellFontUsed + CellFormat)
           .rgbAttr3 = CByte(Alignment)
           .intValue = CInt(value)
         End With
         Put #FileNumber, , INTEGER_RECORD
   
   
      Case ValueTypes.xlsnumber
         Dim NUMBER_RECORD As tNumber
         With NUMBER_RECORD
           .opcode = 3
           .Length = 15
           .Row = Row%
           .col = col%
           .rgbAttr1 = CByte(HiddenLocked)
           .rgbAttr2 = CByte(CellFontUsed + CellFormat)
           .rgbAttr3 = CByte(Alignment)
           .NumberValue = CDbl(value)
         End With
         Put #FileNumber, , NUMBER_RECORD
     
     
      Case ValueTypes.xlsText
         Dim b As Byte
         st$ = CStr(value)
         l% = Len(st$)
       
        Dim TEXT_RECORD As tText
        With TEXT_RECORD
          .opcode = 4
          .Length = 10
          'Length of the text portion of the record
          .TextLength = l%
       
          'Total length of the record
          .Length = 8 + l
       
          .Row = Row%
          .col = col%
         
          .rgbAttr1 = CByte(HiddenLocked)
          .rgbAttr2 = CByte(CellFontUsed + CellFormat)
          .rgbAttr3 = CByte(Alignment)
       
          'Put record header
          Put #FileNumber, , TEXT_RECORD
       
          'Then the actual string data
          For a = 1 To l%
             b = Asc(Mid$(st$, a, 1))
             Put #FileNumber, , b
          Next
        End With
     
    End Select
   
    WriteValue = 0   'return with no error
   
Exit Function

Write_Error:
    WriteValue = Err.Number
    Exit Function

End Function

Запись в файл производится так. А вот как вытянуть назад данные не разберусь.
Век живи - век учись!
www.detal-plast.narod.ru

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 24.01.2005 (Пн) 14:57

Я не знаю, какой у файла д.б. заголовок и чем должно начинаться описание ячеек (да и чем оно д. заканчиваться), но их чтение нужно с помощью тех же типов (tInteger и проч.) выполнять:
Код: Выделить всё
Get #FileNumber,CellNumber,tInteger

Позиция будет смещаться на длину tInteger, по идее. Во всяком случае, если режим Random - похожее я делал, когда нужен был собственный формат файла. Да и для Binary наверняка, хотя я-то в binary-режиме работал только с простыми данными - текст + разметка. Типа xml, html
Есть ли у меня вопрос? У меня всегда есть вопрос

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 24.01.2005 (Пн) 22:17

Мысль поймал - что-то уже получается. Но есть вопрос - как определить, какой тип считывается в текущий момент (нужно же определить как-то длину записи, которая изменяется как раз от ее типа) из файла. И как определить номер считываемой ячейки CellNumber - он же не имеет формат (Row,Cell) как мы привыкли и какой используется, в принципе, при записи.
Век живи - век учись!
www.detal-plast.narod.ru

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 8:20

Чудик писал(а):...как определить, какой тип считывается в текущий момент (нужно же определить как-то длину записи, которая изменяется как раз от ее типа) из файла. И как определить номер считываемой ячейки CellNumber - он же не имеет формат (Row,Cell) как мы привыкли и какой используется, в принципе, при записи.
тут главный вопрос - это структура файла. по-идее, когда ты знаешь, что заголовок кончился и что начались ячейки, номер тебе не нужен - ты просто последовательно считываешь следующую порцию в соотв. структуру (а из нее читаешь атрибуты).
Как-то всё вот так вот (я тонкостей не помню, а может и основное помню неправильно, давно было):
В binary-режиме я это делал, теперь вспоминаю. С Random - по другому, канают только однородные записи. Там было несколько разных записей в файле, но я знал, что сначала записывается, например, содержимое структуры (это только пример!)
Код: Выделить всё
Type FileData
  RecordsCount as Long
  NativeDataBase as String
  LastUpdated as Long
End Type

а затем - идут записи типа Record
Код: Выделить всё
Type Record
  FName as String
  LName as String
  Sum as Currency
End Type

соответственно, я читал с начала так:
Код: Выделить всё
Dim FileData_ as FileData
Get #FileNumber,,FileData_

А потом
Код: Выделить всё
Dim mRecord as Record
For I = 1 To FileData_.RecordsCount
Get #FileNumber,,mRecord
...................................
Next I


хотел тебе сбросить тот пример - но нашел только прогу, а исходников нет :? (и прога-то не у меня, нашлась у старого заказчика :) ).

Короче, пробовать надо. И если это правильно, для Excel - все равно надо структуру знать
Есть ли у меня вопрос? У меня всегда есть вопрос


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 18

    TopList