Ответ 1
Одна вещь, с которой вам следует столкнуться, заключается в том, что те методы Filexxxx
официально официально и официально не рекомендуются. При использовании их Intellisense появляется с помощью:
... Функция My позволяет повысить производительность и производительность операций ввода-вывода файлов, чем FileOpen. Для получения дополнительной информации см. Microsoft.VisualBasic.FileIO.FileSystem.
Они говорят о My.Computer.FileSystem
, но есть еще более полезные методы NET.
Сообщение не показывает, как данные будут сохранены, но если это массив любого вида и/или структуры, они по крайней мере субоптимальны, если не устаревают. Это сохранит его в классе, так что числовые данные могут быть сохранены в виде чисел, а вместо массива будет использоваться List
.
Я сделал быстрый файл, похожий на ваш, с некоторыми случайными данными: {"CustName", "Phone", "UserName", "Product", "Cost", "Price", "Profit", "SaleDate", "RefCode"}
:
- CustName присутствует в 70% случаев
- Имя пользователя никогда не отображается
- RefCode присутствует в 30% случаев
- Я добавил SaleDate, чтобы проиллюстрировать это преобразование данных
Ziggy Aurantium, 132-5562, Food Food, 8,26,9,95,1,69,08/04/2016,
Catrina Caison, 899-8599, Точилка ножа, 4,95,6,68,1,73,10/12/2016, X-873-W3
, 784-4182, Паровой компрессор, 11,02, 12,53,1,51,09/12/2016,
Код для анализа CSV
Примечание: это плохой способ анализа CSV. Есть много проблем, которые могут возникнуть, делая это таким образом; плюс требуется больше кода. Он представлен потому, что это простой способ не иметь дело с недостающими полями. См. Правильный путь
' form/class level var:
Private SalesItems As List(Of SaleItem)
SaleItem
- это простой класс для хранения интересующих вас элементов. SalesItems
- это коллекция, которая может хранить только объекты SaleItem
. Свойства этого класса позволяют сохранить стоимость и стоимость как Decimal
и дату как DateTime
.
' temp var
Dim item As SaleItem
' create the collection
SalesItems = New List(Of SaleItem)
' load the data....all of it
Dim data = File.ReadAllLines("C:\Temp\custdata.csv")
' parse data lines
' Start at 1 to skip a Header
For n As Int32 = 0 To data.Length - 1
Dim split = data(n).Split(","c)
' check if it is a good line
If split.Length = 9 Then
' create a new item
item = New SaleItem
' store SOME data to it
item.CustName = split(0)
item.Phone = split(1)
' dont care anout user name (2)
item.Product = split(3)
' convert numbers
item.Price = Convert.ToDecimal(split(4))
item.Cost = Convert.ToDecimal(split(5))
' dont use the PROFIT, calculate it in the class (6)
' convert date
item.SaleDate = Convert.ToDateTime(split(7))
' ignore nonexistant RefCode (8)
' add new item to collection
' a List sizes itself as needed!
SalesItems.Add(item)
Else
' To Do: make note of a bad line format
End If
Next
' show in DGV for approval/debugging
dgvMem.DataSource = SalesItems
Примечания
Как правило, плохая идея хранить что-то, что можно просто вычислить. Таким образом, свойство Profit
:
Public ReadOnly Property Profit As Decimal
Get
Return (Cost - Price)
End Get
End Property
Он не может быть "устаревшим", если цена или цена будут обновлены.
Как показано, использование результирующей коллекции может быть легко отображено пользователю. Учитывая DataSource
, DataGridView
создаст столбцы и заполнит строки.
Правильный путь
String.Split(c)
очень плохая идея, потому что если продукт: "Hose, Small Green"
, он будет рубить это и обрабатывать его как 2 поля. Существует ряд инструментов, которые будут выполнять почти всю работу за вас:
- Прочитайте файл
- Разбор строк
- Сопоставьте данные CSV с классом
- преобразует текст в соответствующий тип данных
- создать экономичный коллектив
Помимо класса все вышеизложенное может быть выполнено всего несколькими строками, используя CSVHelper:
Private CustData As List(Of SaleItem)
...
Using sr As New StreamReader("C:\Temp\custdata.csv", False),
csv = New CsvReader(sr)
csv.Configuration.HasHeaderRecord = True
CustData = csv.GetRecords(Of SaleItem)().ToList()
End Using
Две или три строки кода для чтения, разбора и создания коллекции из 250 элементов.
Даже если вы хотите сделать это вручную по какой-либо причине, CSVHelper может помочь. Вместо того, чтобы создавать для вас List(Of SaleItem)
, вы можете использовать его для чтения и анализа данных:
... like above
csv.Configuration.HasHeaderRecord = True
Do Until csv.Read() = False
For n As Int32 = 0 To csv.Parser.FieldCount - 1
DoSomethingWith(csv.GetField(n))
Next
Loop
Это возвращает поля вам по одному. Он не конвертирует ни даты, ни цены, но он не будет задыхаться от отсутствующих элементов данных.
Ресурсы
- Пятиминутное введение в классы и списки
- CSVHelper
- Класс vs Структура
- File Class содержит подсказки полезных методов