¿Cómo puedo evitar que Excel coma mis deliciosos archivos CSV y excrete datos inútiles?

128

Tengo una base de datos que rastrea las ventas de widgets por número de serie. Los usuarios ingresan los datos y la cantidad del comprador, y escanean cada widget en un programa de cliente personalizado. Luego finalizan el pedido. Todo esto funciona a la perfección.

Algunos clientes quieren una hoja de cálculo compatible con Excel de los widgets que han comprado. Generamos esto con un script PHP que consulta la base de datos y genera el resultado como un CSV con el nombre de la tienda y los datos asociados. Esto funciona perfectamente bien también.

Cuando se abre en un editor de texto como Notepad o vi, el archivo se ve así:

"Account Number","Store Name","S1","S2","S3","Widget Type","Date"
"4173","SpeedyCorp","268435459705526269","","268435459705526269","848 Model Widget","2011-01-17"

Como puede ver, los números de serie están presentes (en este caso dos veces, no todas las series secundarias son iguales) y son largas cadenas de números. Cuando este archivo se abre en Excel, el resultado se convierte en:

Account Number  Store Name  S1  S2  S3  Widget Type Date 
4173    SpeedyCorp  2.68435E+17     2.68435E+17 848 Model Widget    2011-01-17

Como puede haber observado, los números de serie están encerrados entre comillas dobles. Excel no parece respetar los calificadores de texto en archivos .csv. Al importar estos archivos a Access, tenemos cero dificultades. Al abrirlos como texto, no hay problema en absoluto. Pero Excel, sin falta, convierte estos archivos en basura inútil. Intentar instruir a los usuarios finales en el arte de abrir un archivo CSV con una aplicación no predeterminada se está volviendo, digamos, agotador. ¿Hay esperanza? ¿Hay alguna configuración que no haya podido encontrar? Este parece ser el caso con Excel 2003, 2007 y 2010.

atroon
fuente
46
¿puedo dar un +1 solo por el nombre?
tombull89
11
Excel does not seem to respect text qualifiers in .csv files- las comillas dobles no son calificadores de texto, simplemente permiten comas en sus datos, si no usa comas en sus datos, entonces no tienen sentido . Todos los datos en un archivo CSV no están tipificados, por lo que Excel solo puede adivinar que su número de serie grande es un número , y es entonces cuando se ejecuta con la precisión máxima de Excel de 15 dígitos, que es lo que está truncando sus números.
DMA57361
1
Excel no parece respetar todas las comas entre comillas dobles. Considere "12 de agosto de 2012" Excel convierte eso en basura también.
zundarz
55
Quiero mencionar esta pregunta SU . Explica qué opciones tiene al tratar con CSV en Excel.
nixda
1
@nixda ¡Gracias! Esas son sugerencias útiles, especialmente para los usuarios más experimentados. Mi problema es casi un problema humano, ya que Excel se asocia con archivos .csv, y la gente ve el ícono y hace doble clic (porque así es como se abren las cosas), y luego generalmente presiona Guardar (porque siempre decimos ellos para salvar!), y todo está perdido. Pero definitivamente usaré sus métodos cuando sea posible.
atroon el

Respuestas:

58

Pero Excel, sin falta, convierte estos archivos en basura inútil.

Excel es basura inútil.

Solución

Me sorprendería un poco si cualquier cliente que deseara sus datos en formato Excel no pudiera cambiar el formato visible en esas tres columnas a "Número" con cero decimales o "texto". Pero supongamos que un breve documento de instrucciones está fuera de discusión.

Sus opciones son:

  1. Agregue un carácter no numérico, no un espacio en blanco en sus números de serie.
  2. Escriba un archivo xls o un archivo xlsx con un formato predeterminado.
  3. Engaña y saca esos números como fórmulas ="268435459705526269","",="268435459705526269"(también puedes ="268435459705526269",,="268435459705526269"ahorrarte 2 caracteres). Esto tiene la ventaja de mostrar correctamente, y probablemente sea generalmente útil, pero sutilmente roto (ya que son fórmulas).

Tenga cuidado con la opción 3, porque algunos programas (incluidos Excel y Open Office Calc), ya no tratarán las comas dentro de los =""campos como escapó. Eso significa ="abc,xyz"que abarcará dos columnas y romperá la importación.

El uso del formato de "=""abc,xy"""resuelve este problema, pero este método aún lo limita a 255 caracteres debido al límite de longitud de la fórmula de Excel.

Tyler
fuente
1
En realidad, eso no es ser duro. Copie y pegue uno de los números anteriores en Excel, luego cambie el formato de número como se sugiere. Excel cambia el valor, lo que resulta en basura.
Joe Internet
1
@ Joe, era demasiado superficial en mi visión general inicial. Excel efectivamente está produciendo basura, y en sí mismo es basura. He actualizado mi respuesta para reflejar eso. Una opción podría ser tener un "csv de Excel" y también tener un "csv que valga la pena"
Tyler
2
@Tyler: no creo que Excel sea basura, solo digo que OP era correcto que estaba produciendo basura en este caso. En realidad es una muy buena pregunta, sin una solución aparentemente elegante.
Joe Internet
1
Se ha sugerido la opción Formatear celdas ... y he intentado usarla. En este caso, en el momento en que abre el archivo, Excel parece convertir los números de serie a notación científica (de acuerdo, no inesperado) y arroja la precisión. Cuando los cambia a un número o texto, la cadena no vuelve. Esa es realmente la esencia del problema. Sin embargo, la salida como fórmulas puede hacerlo ... No pensé en eso.
atroon el
99
@ DMA57361 El comportamiento no se espera, es determinable. La precisión numérica está bien documentada, así como Excel no lee los CSV. La falta de advertencia y el descarte silencioso de datos es absurdo. El hecho de que ni siquiera pueda decirle a Excel cómo importar los datos es igualmente absurdo. ¿Se necesita la negatividad ? No, pero la honestidad es la mejor política y así es como me siento.
Tyler
42

Tuvimos un problema similar en el que teníamos archivos CSV con columnas que contenían rangos como 3-5 y Excel siempre los convertía en fechas, por ejemplo, 3-5 sería el 3 de marzo, después de lo cual volver a numérico nos dio un entero de fecha inútil. Lo solucionamos por

  1. Cambiar el nombre de la extensión CSV a TXT
  2. Luego, cuando lo abrimos en Excel, esto activaría el asistente de importación de texto
  3. En el Paso 3 de 3 en el asistente, le dijimos que las columnas en cuestión eran texto e importaban correctamente.

Podrías hacer lo mismo aquí, creo.

asistente de importación de texto

Salud

usuario65525
fuente
2
+1 por ser la forma correcta de hacerlo. (Editar: lo siento tuvo que editar un poco para aclarar la solución)
Jay
2
No tiene que cambiar el nombre de su archivo. Simplemente use el asistente de importación Shift-seleccione todas las columnas y elija como texto.
nixda
1
El Asistente de importación de texto es LA respuesta. Todas las demás soluciones son hackers innecesarios que resultan de no entender cómo usar Excel para ver y editar CSV.
Excellll
1
@Excellll, haciendo un archivo a la vez seguro. Al automatizar este proceso, la "piratería innecesaria" a menudo salva el día.
Parrish Husband
1
Esto es completamente inútil cuando los usuarios estándar utilizan Excel para mostrar archivos CSV. Antes de intentar explicar cómo usar el asistente de importación de texto a ~ 15 usuarios de oficina con habilidades para principiantes, prefiero escribir el código fuente del documento Excel por mí mismo.
northkildonan
8

La mejor solución es generar un libro de trabajo XML. Me gusta esto:

<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  </OfficeDocumentSettings>

  <ss:Worksheet ss:Name="Sheet 1">
    <Table>
    <Column ss:Width="100"/>
    <Column ss:Width="100"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="80"/>
    <Column/>

    <Row>
      <Cell><Data ss:Type="String">Account Number</Data></Cell>
      <Cell><Data ss:Type="String">Store Name</Data></Cell>
      <Cell><Data ss:Type="String">S1</Data></Cell>
      <Cell><Data ss:Type="String">S2</Data></Cell>
      <Cell><Data ss:Type="String">S3</Data></Cell>
      <Cell><Data ss:Type="String">Widget Type</Data></Cell>
      <Cell><Data ss:Type="String">Date</Data></Cell>
    </Row>

    <Row>
      <Cell><Data ss:Type="String">4173</Data></Cell>
      <Cell><Data ss:Type="String">SpeedyCorp</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">x</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">848 Model Widget</Data></Cell>
      <Cell><Data ss:Type="String">2011-01-17</Data></Cell>
    </Row>


    </Table>
    <x:WorksheetOptions/>
  </ss:Worksheet>
</Workbook>

El archivo debe tener la extensión .xml. Excel y OpenOffice lo abren correctamente.

veinte cervezas reservadas
fuente
¿Quiere decir que el OP debe usar un script PHP para convertir la base de datos en formato XML?
Prasanna
2
Mucho más limpio que hacer que los usuarios abran .csv en Excel o estropeen su CSV para que solo Excel pueda entender su CSV. Ni siquiera es ese complejo esquema.
binki
¿Dónde se documenta este estándar? Me gustaría saber más sobre los tipos de datos disponibles.
John Doherty
1

Mi solución: tengo el mismo problema con la importación de números de serie. No tienen que tratarse como números, es decir, no se realizan funciones matemáticas en él, pero necesitamos el número completo allí. Lo más simple que tengo es insertar un espacio en el número de serie. por ejemplo, "12345678 90123456 1234". Cuando Excel lo importe, se tratará como texto en lugar de como numérico.

Peterlip
fuente
0

Tenía números de cuenta largos siendo ilegibles.

Así es como lo arreglé:

Abra su archivo.csv en Libre Office / Open Office (puede que tenga que especificar delimitadores, etc.) y luego guarde el archivo como un archivo XML de Excel.

Luego abra este archivo en Excel y verá que las columnas ya no se cambian a formato científico o lo que sea. Para estar seguro, haga clic derecho en la columna y establezca explícitamente el formato como Texto, luego guárdelo como formato de archivo Excel.

¡Abra el archivo de formato de Excel y la columna aún debería estar bien!

usuario127379
fuente
1
Si bien esto podría trabajar, tratando de explicar a alguien que sólo habla Inglés roto por qué tendría que utilizar una suite de oficina diferente crea los mismos problemas que los que resuelve. El software alternativo a M $ Office es bueno en mi opinión, pero me doy cuenta de que no puedo convertir a todos.
atroon
0

El Asistente de importación es la mejor solución para usuarios ocasionales y situaciones únicas. Si necesita una solución programática, puede usar el método QueryTables.Add (que es lo que el Asistente de importación está usando detrás de escena).

Workbooks.Add
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & "C:\myfile.csv", Destination:=Range("$A$1"))
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 437
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = False
    .TextFileCommaDelimiter = True
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(1, 2, 2) 'Edit this line. Add a number for each column, 1 is general, 2 is text. Search the internet for other formats.
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
End With
PBeezy
fuente