cha*_*lie 12 .net vb.net csv import-csv
我正在尝试使用以下代码将CSV文件读入我的VB.net应用程序:
While Not EOF(1)
Input(1, dummy)
Input(1, phone_number)
Input(1, username)
Input(1, product_name)
Input(1, wholesale_cost)
Input(1, dummy)
Input(1, dummy)
End While
Run Code Online (Sandbox Code Playgroud)
我的CSV文件(如文本)如下所示:
Customer Name,Phone Number,Username,Product,Wholesale Cost,Sales Price,Gross Profit, Customer Reference
,00000000000,00000000000,Product Name,25.00,35.00,10.00,
,00000000000,00000000000,Product Name,1.00,1.40,0.40,
Run Code Online (Sandbox Code Playgroud)
如您所见,并非所有字段都包含在内,因此在读取文件时会显示错误,因为它无法到达行尾.
我该如何处理这种类型的文件?
有时字段会在某些行上存在,而其他字段则不存在.
UPDATE
我已经尝试过Zenacity提供的答案,但是当尝试sArray(1)在循环内部使用时它会返回Index was outside the bounds of the array
Ňɏs*_*arp 11
您应该掌握的一件事是,这些Filexxxx方法几乎都是正式和正式弃用的.使用它们时,Intellisense弹出:
...与FileOpen相比,My功能为文件I/O操作提供了更高的生产力和性能.有关更多信息,请参阅Microsoft.VisualBasic.FileIO.FileSystem.
他们在谈论My.Computer.FileSystem但有一些更有用的NET方法.
该帖子没有揭示数据将如何存储,但如果它是任何种类和/或结构的数组,那么如果不过时则至少是次优的.这会将它存储在一个类中,以便数字数据可以存储为数字,而a List将用于代替数组.
我用一些随机数据制作了一个类似于你的快速文件{"CustName", "Phone", "UserName", "Product", "Cost", "Price", "Profit", "SaleDate", "RefCode"}:
Ziggy Aurantium,132-5562,Cat Food,8.26,9.95,1.69,08/04/2016,
Catrina Caison,899-8599,Knife Sharpener,4.95,6.68,1.73,10/12/2016,X-873- W3
,784-4182,蒸气压缩机,11.02,12.53,1.51,09/12/2016年,
注意:这是解析CSV的一种不好的方法.这样做有很多问题可以解决; 加上需要更多代码.它的呈现是因为它是一种不必处理缺失字段的简单方法.看到正确的方式
' form/class level var:
Private SalesItems As List(Of SaleItem)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
注意
存储可以简单计算的东西通常是个坏主意.所以这个Profit属性是:
Public ReadOnly Property Profit As Decimal
Get
Return (Cost - Price)
End Get
End Property
Run Code Online (Sandbox Code Playgroud)
如果更新成本或价格,它永远不会"陈旧".
如图所示,使用得到的集合可以非常容易地显示给用户.给定a DataSource,DataGridView将创建列并填充行.
String.Split(c)这是一个非常糟糕的主意,因为如果产品是:"Hose, Small Green"它会将其切碎并将其视为2个字段.有许多工具可以为您完成几乎所有工作:
除了课程,以上所有内容都可以使用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
Run Code Online (Sandbox Code Playgroud)
两行或三行代码,用于读取,解析和创建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
Run Code Online (Sandbox Code Playgroud)
这将逐个返回给您的字段.它不会转换任何日期或价格,但它也不会扼杀丢失的数据元素.
资源
警告:如果CustomerName或ProductName值可以包含逗号
(.ie CustomerName = "Callaway , Mark"),则无法使用该String.Split()方法.并且最好搜索第三方csv解析器,或者你可以使用TextFieldParserClass - > MSDN文章
您可以点击此链接了解如何使用导入csv TextFieldParser
早些时候我遇到使用SQL Server Integration Services导入Csv文件的问题(字段包含分隔符),你可以看看(Vb.net中的代码):
我的答案是假设缺少的字段总是来自行的右侧,而字段值不包含逗号 (否则@Plutonix答案就是您要查找的内容)
使用此代码,您将能够导入缺少字段的行.
您必须从csv文件中读取每一行,","使用以下代码计算此行中的出现次数
Line.Count(Function(c As Char) c = ",")
Run Code Online (Sandbox Code Playgroud)
如果count小于7(8列),则会添加缺失","
String.PadRight((7 - intCommaCount), ",")
Run Code Online (Sandbox Code Playgroud)
注意:如果缺少逗号,则可以使用左侧String.PadLeft((7 - intCommaCount), ",")
并将该行拆分为Item属性
我创建了以下Item类
Public Class MyItem
Public Property CustomerName As String
Public Property PhoneNumber As String
Public Property Username As String
Public Property Product As String
Public Property WholesaleCost As String
Public Property SalesPrice As String
Public Property GrossProfit As String
Public Property CustomerReference As String
Public Shared Function CreateObjectFromLine(ByVal Line As String) As MyItem
'Count Comma occurence in Line
Dim intCommaCount As Integer = Line.Count(Function(c As Char) c = CChar(","))
Dim strTemp = Line
'Add missing comma's
If intCommaCount < 7 Then
strTemp = strTemp.PadRight((7 - intCommaCount), ",")
End If
'Split Line and return MyItem Class
Dim str() As String = strTemp.Split(",")
Return New MyItem With {.CustomerName = str(0),
.PhoneNumber = str(1),
.Username = str(2),
.Product = str(3),
.WholesaleCost = str(4),
.SalesPrice = str(5),
.GrossProfit = str(6),
.CustomerReference = str(7)}
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
我使用以下代码从CSV文件导入数据
Dim SalesItems As New List(Of MyItem)
Dim csvFile As String = "C:\1.csv"
Using csvStreamReader As New IO.StreamReader(csvFile)
While Not csvStreamReader.EndOfStream
Dim strLine as string = csvStreamReader.ReadLine
' Skip Header
If strLine.StartsWith("Customer Name") Then Continue While
Dim item As MyItem = MyItem.CreateObjectFromLine(strLine)
SalesItems.Add(item)
End While
End Using
'Showing Result in a DataGridView
dgvItems.DataSource = SalesItems
Run Code Online (Sandbox Code Playgroud)
注意: 这是一个简单的例子,需要添加错误处理Try... Catch,Null检查
| 归档时间: |
|
| 查看次数: |
1425 次 |
| 最近记录: |