Excel: Error when CSV file starts with “I” and “D”
support.microsoft.com
support.microsoft.com
I wish we had more of the former and less of the latter. I suspect no forum is ever safe from eternal September.
Something like this could filter out the "random geek wanna-be with an axe to grind" type post.
How would, say, something like Thompson's "Trusting Trust" (though I suppose that was published in ACM or IEEE), or a Dijkstra or Pike blog post, rate?
Comments from, say, Linus Torvalds on the LKML, or Lennert Pottering on systemd, or Bill Gates' various book recommendations, etc.?
It seems like if parsing fails it should throw an exception and fallback to regular csv parsing.
Am I missing something?
Any interesting stories to share? I think we'd all be interested.
Mind if I ask a question directly related to one of my comments a few days ago? I was lamenting the fact that the ASCII codes 29, 30, 31 (Group, Record, and File separators) never really became widely implemented, as these were specifically designed to delimit data. Ie, one could easily include commas, new lines/carriage returns, etc in data cells without clashing. But instead CSV seems to be the most common standard for tabular data.
Were these ASCII codes ever considered for tabular files?
Thanks.
At Yahoo, the typical delimiters for logs and whatnot were ctrl+a, ctrl+b, etc. It was slightly nicer than CSV, but only slightly. It was mostly nicer when manually inspecting files with columns that had embedded commas (that otherwise would have been escaped). The machines don't care, and for any interesting processing you'd often end up with escaping anyway.
Emacs can edit files in this format without any extra work (it displays them as ^\, ^_, etc., with a different text color so that you can easily distinguish them from character sequences like "^" followed by "\") but maybe you mean to say that Emacs by itself doesn't understand the hierarchical structure of such a file.
This is easily fixed. You can get Emacs forms-mode for a file with these delimiters as follows:
(setq forms-field-sep "\036")
(setq forms-multi-line "\037")
(setq forms-read-file-filter 'forms-replace-gs-with-newlines)
(setq forms-write-file-filter 'forms-replace-newlines-with-gs)
(setq forms-file "fsgsusrs.data")
(setq forms-number-of-fields (forms-enumerate '(name aliases wikipedia employer notes)))
(setq forms-format-list
(list
"Project for a New American Century conspirators\n\n"
"\n Name: " name
"\n Aliases: " aliases
"\n Employer: " employer
"\nWikipedia URL: " wikipedia
"\n\nNotes:\n\n" notes))
(defun forms-replace-newlines-with-gs ()
(goto-char (point-min))
(while (search-forward "\n" nil t)
(replace-match "\035" nil t)))
(defun forms-replace-gs-with-newlines ()
(goto-char (point-min))
(while (search-forward "\035" nil t)
(replace-match "\n" nil t)))
It took me 35 minutes to write this "special editor for such files"; thus your argument is invalid.You might further argue that this would create incompatibilities between different systems and so of course everyone would just use the same data file format. Even today, this seems implausible — JSON, various dialects of CSV (with tabs, commas, doublequote-delimited commas, pipes, and colons being the most common delimiters), SQL dumps, and HTML are all in common usage — and in the context of the 1960s and 1970s it seems even less founded. Remember that there were at least five widely used conventions for how to separate lines in ASCII text files up to the 1980s: \r\n (from teletypes), fixed-width records of 80 bytes (from punched cards), \n (from Unix), \r (from PARC, used in Smalltalk, Oberon, and the Macintosh), and \xfe (Pick, see below). And the PDP-10 used a six-bit variant of ASCII they called SIXBIT, the PDP-11 used ASCII, IBM used EBCDIC, and UNIVAC used FIELDATA.
This is a time when even computers from the same manufacturer couldn't agree on how many bits were in a character, much less how to delimit fields in data files. Thus even my attempt to save your argument is invalid.
Interestingly, there was a popular system that worked this way, with non-printable delimiters to divide up different levels of a hierarchical data structure represented as a string: Pick. But Pick didn't use FS, GS, RS, and US in storage either, and although it did use them in the user interface, it used them backwards. Pick's "items" (usually used like records in a database, but accessed like files in a directory) were divided into "attributes", corresponding to database fields, by the "attribute mark", byte 254, displayed as "^" (or often as a line break) and entered as control-^ (RS); the attributes were divided into "values" by the "value mark", byte 253, displayed as "]" and entered as control-] (GS); and values could be divided into "sub-values" by the "sub-value mark", byte 252, displayed as "\" and entered as control-\ (FS).
Pick also reserved byte 255 to mark the ends of items, like NUL (\0) in C, or ^Z (\x1A) in CP/M or early MS-DOS. It called it the "segment mark", displayed as "_", and it was entered with as control-_ (US).
Note that ASCII-1963 had eight separator control characters instead of just four: http://worldpowersystems.com/J/codes/#S0
"If you move your mouse pointer continuously while the data is being returned to Microsoft Excel, the query may not fail. Do not stop moving the mouse until all the data has been returned to Microsoft Excel."
https://support.microsoft.com/en-us/kb/168702
I've always wanted to know why Method 2 works!
Google Sheets are surprisingly the worst in this department. It's pretty much impossible to prevent Google Sheets to convert 5/7 to a date and 0123 to a number (losing the leading 0 of course and rendering the data invalid). No, ' is not the answer.
At G+, Noah Friedman, who's part of the team who worked on the code, has inquired occasionally about the availability of some early Emacs code. Pre-1990, if I recall.
I'm not sure he ever turned that up even as a standalone tarball, let alone from a revision control repository.
It seems to me that Microsoft by now could have improved its tests. If the first two letters are "ID", but if "there are no valid SYLK codes after the 'ID' characters," then maybe it was never meant to be an SYLK file. If the file's suffix is .csv, then maybe you should just treat it as a CSV file. If the file's suffix is .txt, then maybe you should treat it as a text file.
echo MZ is my name my name is MZ. I'm the hippest loader bug from the sea to the sea! >foo.txt
.\foo.txt
Basically you get a dialog saying the text file isn't a compatible executable. If you change the MZ to anything else, it opens in notepad.
"This version of foo.txt is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher."
32-bit Windows should fail a little later in the execution process; it can run 16-bit software, but your text file is missing the rest of the MZ-format header.
[fred@dejah launch]$ chmod +x foo.txt [fred@dejah launch]$ ./foo.txt fixme:winediag:start_process Wine Staging 1.9.12 is a testing version containing experimental patches. fixme:winediag:start_process Please mention your exact version when filing bug reports on winehq.org. winevdm: Cannot start DOS application E:\launch\foo.txt because the DOS memory range is unavailable. You should install DOSBox. [fred@dejah launch]$
I have Wine installed. Same defect as Windows, which is either good or bad -- this is hard to determine.
At least, the hint of installing DOSBox is reasonable. So, let's do that:
[fred@dejah launch]$ sudo dnf install dosbox
and try it again:
[fred@dejah launch]$ ./foo.txt fixme:winediag:start_process Wine Staging 1.9.12 is a testing version containing experimental patches. fixme:winediag:start_process Please mention your exact version when filing bug reports on winehq.org. DOSBox version 0.74 Copyright 2002-2010 DOSBox Team, published under GNU GPL. --- ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused
CONFIG: Generating default configuration. Writing it to /home/fred/.dosbox/dosbox-0.74.conf CONFIG:Loading primary settings from config file /home/fred/.dosbox/dosbox-0.74.conf CONFIG:Loading additional settings from config file /home/fred/.wine/dosdevices/c:/users/fred/Temp/cfgcbaf.tmp MIXER:Can't open audio: No available audio device , running in nosound mode. ALSA:Can't subscribe to MIDI port (65:0) nor (17:0) MIDI:Opened device:none [fred@dejah launch]$
"If the file's suffix is .csv, then maybe you should just treat it as a CSV file"
doesn't make me any happier, because there are a lot of slight variations on CSV files or a lot of different ways you might want to load a CSV file (perhaps you'd like to specify the character set, or set columns to be text or date format, or not have leading zeroes stripped or numbers in brackets turned into negative values), and if I absentmindedly name them .csv then again I can't use the full loader, because Excel knows best.
And if you want to read a CSV file with a VB macro it's even worse, because you can specify all the parameters but it just silently overrides them all with the CSV defaults just because the file extension is CSV. Hours of debugging spent on that...
1. Open new file
2. Type "Bush hid the facts"
3. Save the file
4. Open the file
5. The content of the file have changed to "畂桳栠摩琠敨映捡獴"
:)
> A SYLK file is a text file that begins with "ID" or "ID_xxxx", where xxxx is a text string. The first record of a SYLK file is the ID_Number record. When Excel identifies this text at the beginning of a text file, it interprets the file as a SYLK file. Excel tries to convert the file from the SYLK format, but cannot do so because there are no valid SYLK codes after the "ID" characters. Because Excel cannot convert the file, you receive the error message.
This is usually called "magic string" or "magic number" (https://en.m.wikipedia.org/wiki/Magic_number_(programming)). It has nothing to do with the comma, and everything to do with SYLK using a pretty risky magic string (ID) and Excel not having a "try SYLK, if that fails, try as csv".
tl;dr: this is about guessing the input format and has nothing to do with the delimiter.
Although you'd just run into other pathetic cases with such an informal format (CSV, not SYLK). But hey, I need to interchange formats with some IT guys and don't have a big IT department (ready) and they don't want to parse XLS(X), so I just use CSV. Now you have two problems.
I believe in the Canadian French locale (and maybe many other locales), ";" is considered a separator (a "," equivalent).
Thus 'ID;P' would be a valid header for SYLK and e.g. for German "CSV"s.
The problem of discriminating between csv and SYLK files is unsolvable, as every file with only ASCII characters and no commas or quotes is a valid csv file (with one column) and there are valid SYLK files in that set.
I suspect you're thinking of a comma as ASCII 44. If your source text isn't ASCII then it's just not this simple.
In other words, if you take CSV and make it completely useless for hand-editing in a text-editor by taking it 90% of the way to being a length-prefixed binary encoding, you'll have what the programmer's mind intuitively jumps to as "what CSV should be."
Another one would have been to write numbers in a CSV file in the American format and just adapt them to the current locale when reading them.
Both would be a more sensible interpretation of your GP.
That'll make the world a better place wouldn't it?.....
ColA;ColB;ColC
1,618;2,718;3,14159
And in fact, to open an "American" CSV file in Excel you either have to set Windows to American locale settings, or use the text import wizard or the "text to columns" feature. If you don't use the correct settings, Excel will not complain, but corrupt the data (sometimes subtly).I hope you agree that it is INSANE to make a file format depend on locale settings. As someone who writes software for scientists in Europe it leads to endless confusion and annoyance.
(And even if you do everything correctly, Excel will still mangle certain CSV files, interpreting phone numbers as dates etc...)
(Once long ago in my youth, I got bitten when the quoting app I was writing worked fine on our test server, but got the day and month fields swapped on our customer's server. And that was when I learned that you shouldn't pass dates through ODBC as text strings...
SQL Server was parsing dates based on the Windows date settings. Our test server was set to the default U.S. date format but the customer's server was set to DD/MM/YY, or vice versa, I can't remember now. What made it worse was that we handed the system over early in a month, and it worked fine for over a week...)
When I admire Microsoft, it's most often because despite nearly 4 decades of bloat to support, they still can ship reliable software to millions.
That's way up there with the "you can't drag stuff here, should've dragged it a few px further" from Win98.
I do think it should be giving back a more descriptive error though, possibly one informing the user that it thinks it is a SYLK file and giving them the option to interpret it differently.
How many SYLK files did you see recently, e.g. within the last 30 years? For me, the result is 0 (zero). As compared to innumerable swarms of CSVs of all flavors. Yet even MSO2013 prefers Yonder Hiftorical Curioufity; whence Excel's fondness and preference for obscure and rare formats, I have no idea.
And yes, giving user at least an intelligible error message would be nice (I hold no illusions that popping up a selection would be a complex feat: import logic is usually a gnarly place).
You could even do something as trivial as "if Excel fails to open the file as SYLK, try again as CSV" and cut at least 99% of the problem away.
After many years, I still have to slap myself when I catch myself thinking this way. Unless you know the architecture of the software, I've learned that it's often significantly harder than you imagine to fix seemingly simple and obvious bugs without breaking something else.
They could have fewer bugs per feature than almost any other product after being stable and popular for so long. But they choose not to make that a goal.
At least now I know why!
For plain text files, it's a little bit different, but there's no excuse for this problem happening in a binary file format.
Switching topics, I'm imagining a solution to this problem where you don't actually know which format it is, you have a streaming processor for each thing it could be, and feed it to each processor one character at a time. Whenever a processor returns an error, drop it from the list. If the last processor in the list returns and error, report that error to the user along with which format that processor was for. If multiple peocessors complete successfully, you'll have to either rank them, or ask the user what format it is.
Interesting idea on passing the file to multiple parsers simultaneously, although I don't see a benefit over trying them serially.
I particularly like the step by step explaination of how to add an apostrophe at the begining of the first line with a description of which keyboard key to press...
I know that's boring but this is one of those generational pieces of knowledge like "keep your docs up to date" that we need to build into software training somehow. (Or rather, this bug is not important, but the kind of training that imparts this knowledge will be vital in building a real software profession)
But yeah, it's a real WTF
ID,Name 1,??? ???? 2,Kevin Dub?is
so take care to always save such documents as .xmlx.
(If you convert them to your local codepage and import that - when at all relevant - it will be saved in the local codepage, so less risk of data loss.)
A BOM is abnormal and not recommended in UTF-8, it's basically a shitty MS hack: the BOM is necessary to detect endianness differences between the document and the host system, endianness has no impact impact on UTF-8.
And as freak_nl above notes, Excel uses locale-dependent field separators, so in some countries/locales it will try to import "CSV" with semicolon separators.
Someone at some point decided that the Dutch use semi-colons instead of commas to delimit tabulated data, and decided to apply this logic to CSV files as well. I would like to know the history behind such a decision! Switch your locale to English US, and it opens normally.
LibreOffice just opens the CSV and asks the user to confirm the delimiter and what not regardless of locale.
CSV libraries tend to adhere to it (and often support additional options encountered in the wild as well); e.g., Apache Commons CSV².
Exactly. Unfortunately, double-clicking the file does not trigger that dialogue. You would be surprised how many IT-staffers simply give up at that point („Can I get the raw data?”, „Sure, here is the automatically generated CSV dump.”, „I can't open it…”).
For an operation that is done literally millions of times around the world each year, Microsoft seems to pretend that it's some bizarre corner case. I know CSV is a messy format, but you can do better Microsoft. Even a week or two of work on that could make it much much better.
A VBA import routine will always run in the US locale. However, csv files containing dates formatted according to other locales will have their days and months switched as long as the day is not bigger than 12.
Also see https://en.m.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)
The workaround needs it's own workaround :)
It’s really silly to see applications have trouble understanding data. Even on macOS, where "file" is installed, the graphical interface sometimes fails to open/preview something that the command-line "file" describes perfectly (i.e. if it’s really text, just show me the text).
And even if they did, chances were that transporting the file between machines (no, you couldn't move a floppy disk between machines, even if both machines had a floppy disk. Typical transport involved sending data over a serial line that only guaranteed to transfer 7 bits/byte, another reason why SYLK is ASCII) lost the extension.