I am using FileHelpers to read a CSV file that have hundreds of columns but I only need the first twenty or so, so while creating the mappings in the class I only put those twenty columns.
When do the parsing, I get the following exception
Delimiter ',' found after the last field 'CompanyDivision' (the file
is wrong or you need to add a field to the record class)
I read in other answers that a hack for this is to put dummy fields for the rest of the columns you don't want to read but, as I said, I have hundreds of those.
Is there a way to configure the engine to stop after a certain number of columns? or is there a way to extend or modify the engine to do this?
You can try adding an array dummy field:
private string[] mDummyField;
With that the rest of the fields will be in that field. You must use the last version of the library.
Related
As the question says, using the FileHelpers library I am attempting to generate a CSV file along side a report file. The report file may have different (but finite) inputs/data structures and hence my CSV generation method is not explicitly typed. The CSV contains all of the report data as well as the report's header information. For my headers, I am using the class object properties because they are descriptive enough for my end use purpose.
My relevant code snippet is below:
// File location, where the .csv goes and gets stored.
string filePath = Path.Combine(destPath, fileName);
// First, write report header details based on header list
Type type = DetermineListType(headerValues);
var headerEngine = new FileHelperEngine(type);
headerEngine.HeaderText = headerEngine.GetFileHeader();
headerEngine.WriteFile(filePath, (IEnumerable<object>)headerValues);
// Next, append the report data below the report header data.
type = DetermineListType(reportData);
var reportDataEngine = new FileHelperEngine(type);
reportDataEngine.HeaderText = reportDataEngine.GetFileHeader();
reportDataEngine.AppendToFile(filePath, (IEnumerable<object>)reportData);
When this is executed, the CSV is successfully generated however the .AppendToFile() method does not add the reportDataEngine.HeaderText. From the documentation I do not see this functionality to .AppendToFile() and I am wondering if anyone has a known work-around for this or a suggestion how to output the headers of two different class objects in a single CSV file using FileHelpers.
The desired output would look something like this however in a single CSV file (This would be a contiguous CSV obviously; not tables)
Report_Name
Operator
Timestamp
Access Report
User1
14:50:12 28 Dec 2020
UserID
Login_Time
Logout_Time
User4
09:33:23
10:45:34
User2
11:32:11
11:44:11
User4
15:14:22
16:31:09
User1
18:55:32
19:10:10
I have looked also at the MultiRecordEngine in FileHelpers and while I think this may be helpful, I cannot figure out based on the examples how to actually write a multirecord CSV file in the required fashion I have above; if it is possible at all.
Thank you!
The best way is to merge the columns and make one big table then make your classes match the columns you need to separate them out when reading. CSV only allows for the first row to define the column names and that is optional based on your use case. Look at CSVHelper https://joshclose.github.io/CsvHelper/ it has a lot of built-in features with lots of examples. Let me know if you need additional help.
I successfully made a c# class that uses Jet to execute a SELECT string on a csv file. However, I really need an UPDATE and/or INSERT statement and Jet apparently won't allow it. I've been looking into using LINQ, but can't seem to find any examples of an UPDATE clause for LINQ either. Anyone know about this? or perhaps a different class than LINQ that could accomplish this?
Basically, I want to read a csv file into memory and query on it (select columns, or distinct, etc), which is fine with Jet, but I also want to update rows and modify the text file.
basically:
UPDATE table
SET col3 = 42
WHERE col1='mouse', col2='dolphins';
and have that take effect data read from csv.
also, I can't figure out how to access columns by name with LINQ. any advice?
so far, a constructor for my class seems to parse the file ok (I can see it in the watch and immediate windows), but I don't know how to move on from here:
string Method = this.ToString();
this.strFilePath = filePath;
this.strDelim = delim;
Logger.Debug("Starting", Method);
try
{
fileLines = File.ReadAllLines(filePath);
}
catch (Exception Ex)
{
Logger.Error(Ex, Method);
}
this.fileTable = fileLines.Select(l => l.Split(delim));
Ignore the 'Logger', this is an in-house class that writes things to a log for our own purposes.
What you're asking can't easily be done, due to the way text files are organized.
In general, you can't arbitrarily update a text file like you can a file of records. Consider, for example, the following text file.
line1,43,27,Jim
line2,29,32,Keith
Now, you want to change the 43 on line 1 to 4300. That involves adding two characters to the file. So you end up having to move everything after 43 down two spaces and then insert the 00. But moving everything down two spaces requires extending the file and moving the entire text.
Text files are typically used for sequential access: reading and appending. Insertion or deletion affects the entire file beyond the point of modification. Unless you're going to re-write the entire file on every change, you simply do not want to use a text file for holding data that changes frequently.
I have got text file that have next structure:
id=123
name=value
year=2013
Where first part (id, name, year) is name of column, and the last part - the data that I need to past in column. I have not any idea how to do it.
1. I am reading files line by line
2. ??
I have only stupid idea to replace '=' with query and to try run it. But it's look like bad idea...
Also I need to check if the data present in DB.
Upload your text file
Read it line by line
Update DB
How I would do it
Upload text file
Create a List of objects that has those values and has implemented
validation.
Read every line and every three lines try to construct a valid
object of that type in case of errors since I'd had to use regex or something similar to distinguish key from value.
Update database via LINQ2SQL with using my list of objects
I'm using the LumenWorks CsvReader to parse a file with the following structure.
heading1,heading2,heading3
data1,data2,data3,data4,data5
The code detects that I've got three fields per row because I've got three headings. It happily allows me to parse the first row and retrieve data1, data2, and data3, but i can't access data4 or data5. At the very least, I'd like to be able to detect additional fields in the data rows. Does anyone know if this is possible?
Thanks!
It does this because it uses the first row to know how many columns your file has. If you change the first row to "heading1,heading2,heading3,," it will work as expected.
I expect that you won't be able to read the data in those fields. Rather, I expect that an error is being raised and you're not seeing it. This would at least allow you to detect that those other fields exist in the data.
Try setting the DefaultParseErrorAction enum property so that you ensure you're seeing any errors being raised. I would have expected the scenario you describe to trigger a MalformedCsvException (if you have set the DefaultParseErrorAction = ParseErrorAction.ThrowException). You could also set DefaultParseErrorAction = ParseErrorAction.RaiseEvent and then attach an event handler to the ParseError event. Finally, you should be able to just check if the ParseErrorFlag is true after each record.
HTH
I'm trying to create a list that allows me to store multiple instances of a single column.
Say I have a column names "steps" which is a single line of text, and I want the user to be able to add as many as possible.
Can I do this currently in Sharepoint Lists?
Bonus points for allowing me to do it in a LoopUp column, for more complex types.
You will need to create a "Custom Field Type" to do this. Then you can delimit your different lines somehow (the internal columns link Multi-lookup, multi-choice etc use ;# as a delimiter but you can use whatever)
http://msdn.microsoft.com/en-us/library/ms446361.aspx
http://msdn.microsoft.com/en-us/library/bb684919(v=office.12).aspx
http://sharepointmagazine.net/articles/customizing-the-user-experience-of-sharepoint-custom-fields-deep-dive-part-5-of-6