Чтение файла в массив (таблицу)

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

Чтение файла в массив (таблицу)

Сообщение Niko » 14.06.2007 (Чт) 10:54

Добрый день.
У меня есть текстовый файл в котором содержатся данные вида:
---
name1 100 100
name2 150 100
name3 50 200
...
name9000 300 100
---
Мне нужно загрузить эти данные в массив.
Код: Выделить всё
type bbb
  nam as string
  x as double
  y as double
end type

dim BaseT() as bbb


и отобразить их в таблице (FlexGrid)

Код: Выделить всё

Open PathFile For Input As 1
Do Until EOF(1)
    k = k + 1
    Line Input #1, sLine
    sMass = Split(sLine, " ")
    ReDim Preserve BaseT(k)
    BaseT(k).sName = sMass(0)
    BaseT(k).X = Val(sMass(1))
    BaseT(k).Y = Val(sMass(2))
    grdFlex.additem replace(sline," ",vbtab)
Loop

---
все работает но очень долго (около 10-и сек), к примеру в RitchTextBox этот файл загружается "мгновенно".
Подскажите как убыстрить этот процесс.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 14.06.2007 (Чт) 11:04

Ещёбы! Использовать в цикле ReDim Preserve. Так быстро не будет по любому. А по поводу заполнения массива идея такая: раз всё равно заполняется FlexGrid, то может и уже распарсенные значения брать прямо из него? Зачем двойную работу делать? И посмотри в его настройках, может он позволяет использовать другой символ для разделения полей, тогда сможешь избавиться от Replace().

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 11:21

Узким местом является построчное чтение файла. Если длина файла в пределах нескольких мегабайт, то можно смело грузить его целиком в строковую переменную и работать с ней. Правда, алгоритм немного усложнится... Еще можно преобразовать файл в двоичный со структурой:
32 байта - имя
4 байта - x
4 байта - y
и т. д.
тогда считывание в файл можно сделать одной строкой и происходить это будет максимально быстро!

примерно так:
Код: Выделить всё
Type bbb
  nam As String * 32
  x As Single
  y As Single
End Type

dim BaseT() as bbb

fn = freefile
Open PathFile For Binary As #fn
redim BaseT(8999)
GET #fn, 1, BaseT() 'считывание
Close #fn
O, sancta simplicitas!

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 11:27

пробовал отдельно заполнять массив и после этого таблицу таким образом:
Код: Выделить всё
For i = 1 To UBound(BaseT)
    .Rows = i + 1
    .Row = i
    .Col = 0
    .Text = BaseT(i).sName
    .Col = 1
    .Text = BaseT(i).X
    .Col = 2
    .Text = BaseT(i).Y
Next i

массив заполняется примерно 5 сек и таблица около 5-и сек.
Код: Выделить всё
For i = 1 To UBound(BaseT1)
    .AddItem BaseT1(i)
Next i

так быстрее но не сильно. BaseT1 содержит строки с замененными пробелами на vbTab

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 11:36

to pronto разделителем в строке является пробел и длина названия, X и Y может быть разной.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 14.06.2007 (Чт) 11:41

pronto писал(а):Узким местом является построчное чтение файла.


В данном случае не это, а использование нагружаемого контрола типа FlexGrid - добавление идет долго именно в него. Выход - использовать нормальный Grid, а не из поставки VB. Обсуждалось сотни раз, в том числе и на тему какой...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 11:53

2 Niko. При такой организации данных нет необходимости в разделител(е, ях). Длина имени может изменяться от 0 символов до 32. Переменная Single может хранить значения в диапазоне от -3.4x10^38 до -1.4x10^-45 для отрицательных величин и от +1.4x10^-45 до +3.4x10^38 для положительных величин...

З.Ы. Ну и неплохо бы прислушаться к Andrey Fedorov
O, sancta simplicitas!

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 11:57

файл не мой, а грид такой т.к. хочется выделять отдельные ячейки цветом.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 12:02

после считывания файла в массив

Код: Выделить всё
Open NewFilePath For Binary As #fn
Put #fn, 1, BaseT() 'сохранить в двоичном виде
Close #fn


Потом обращаешься моим первым кодом к этому файлу.
O, sancta simplicitas!

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 12:10

но если он уже в массиве, зачем создавать новый файл и считывать его в тот-же массив? :scratch:

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 12:19

Тебе нужно чтобы он (массив) грузился-заполнялся быстро? Если файл обновляется нечасто, то разницу почувствуешь при последующих обращениях к нему (двоичному).
O, sancta simplicitas!

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 12:30

так если я его (массив) уже заполнил мне не нужно обращаться к файлу, все данные есть в массиве.
осталось эти данные загрузить в таблицу (быстро).
сам массив так-же заполнять надо быстро (как в твоем коде) только из файла в его исходном формате.
переписывать исходный файл нет смысла т.к. данные считываются из него 1 раз и файл не нужен.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 13:25

Ладно, я хотел как лучше, но если не надо, тогда вот:

Код: Выделить всё
fn = FreeFile
Open FilePath$ For Binary As #fn
flen = LOF(fn)
Content = Space(flen)
Get #fn, 1, Content
Close #fn

ReDim BaseT(ad)
For i = 1 To flen
   s = Mid$(Content, i, 1)
   q = Asc(s)
   
   Select Case q
      Case 33 To 255 'символы имени и координат
         ts = ts & s
      Case 32 'разделитель - пробел
         v = v + 1
         If v = 1 Then
            BaseT(ad).name = ts
         Else
            BaseT(ad).x = Val(ts)

            v = 0
         End If
         ts = ""
      Case 13 'разделитель строк
         BaseT(ad).y = Val(ts)
         ts = ""
         i = i + 1
         ad = ad + 1
         ReDim Preserve BaseT(ad)
   End Select
Next

'For i = 0 To ad
'   Debug.Print BaseT(i).name, BaseT(i).x, BaseT(i).y
'Next
O, sancta simplicitas!

Niko
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 102
Зарегистрирован: 16.03.2006 (Чт) 14:43

Сообщение Niko » 14.06.2007 (Чт) 14:36

спасибо. работает довольно быстро

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 14.06.2007 (Чт) 16:03

Пожалуйста!
O, sancta simplicitas!

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 14.06.2007 (Чт) 17:39

А еще этот файл можно открыть как Recordset...
На тему как текстовый файл открыть как Recordset - в конференции уже было...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...


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

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

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 73

    TopList