【问题标题】:Excel wrongly converts ranges into dates, how to avoid it?Excel错误地将范围转换为日期,如何避免?
【发布时间】:2013-04-02 01:27:06
【问题描述】:

我有一个 .tsv 文件,其中一些字段的范围是 1 - 4。我想阅读这些字段,因为它们是文字编写的。但是,在打开文件时,excel 会自动将这些范围字段转换为日期。例如1 - 4 转换为4-Jan。如果我尝试将单元格重新格式化为另一种类型,则值已经更改,我只能得到一个无用的数字(39816)。即使范围字段在双引号内,仍然会发生错误的日​​期转换。如何避免这种行为?

【问题讨论】:

  • 不要使用 Excel。 ;) 说真的,创建带有“类型化”单元格的实际 .xls 文件可能是唯一的方法。
  • 我刚刚发现,我的问题与:stackoverflow.com/questions/165042/… 重复——这解决了问题(尽管我必须用特殊的双引号重写字段。不使用 Excel 可能是更好的解决方案:P)
  • 天哪,Excel...! D:很高兴知道这个“解决方案”。
  • 其实我只是在使用 Excel 轻松删除一些列。你能推荐我另一个可以做到这一点的简单的 tsv/csv 阅读器吗?
  • 每当我需要处理这样的事情时,我通常会求助于Numbers,我碰巧已经安装了它,它基本上是Excel Which Don't Suck™。不过,这并不是一个快速简便的选择。 :3

标签: excel date implicit-conversion tsv


【解决方案1】:

我认为您最好使用 excel 中的导入工具,但您可能必须手动将文件扩展名更改为 csv

导入时,请务必为具有这些值的所有列选择文本。

【讨论】:

    【解决方案2】:

    我的问题实际上至少是重复的:

    1) Stop Excel from automatically converting certain text values to dates

    2) Excel: Default to TEXT rather than GENERAL when opening a .csv file

    Excel 的可能解决方案是 1) 将带有特殊双引号的字段(如 "May 16, 2011")写入 "=""May 16, 2011""" 或 2) 使用外部数据向导导入 csv/tsv 文件,然后手动选择您想要的列读取为 TEXT 而不是 GENERAL(可以将字段转换为日期)

    至于我的用例,我只是使用 Excel 来删除一些列。没有一个解决方案对我有吸引力,因为我不想用特殊引号重写 tsv 文件,而且我有数百列,我不想手动选择每一列以读取为 TEXT。

    因此我编写了一个 scala 脚本来按列名过滤 tsv 文件:

    package com.jmcejuela.ml
    
    import java.io.InputStream
    import java.io.Writer
    
    import scala.io.Codec
    import scala.io.Source
    
    import Table._
    
    /**
     * Class to represent tables with a fixed size of columns. All rows have the same columns.
     */
    class Table(val rows: Seq[Row]) {
      lazy val numDiffColumns = rows.foldLeft(Set[Int]())((set, row) => set + row.size)
    
      def toTSV(out: Writer) {
        if (rows.isEmpty) out.write(TableEmpty.toString)
        else {
          out.write(writeLineTSV(rows.head.map(_.name))) //header
          rows.foreach(r => out.write(writeLineTSV(r.map(_.value))))
          out.close
        }
      }
    
      /**
       * Get a Table with only the given columns.
       */
      def filterColumnsByName(columnNames: Set[String]): Table = {
        val existingNames = rows.head.map(_.name).toSet
        assert(columnNames.forall(n => existingNames.contains(n)), "You want to include column names that do not exist")
        new Table(rows.map { row => row.filter(col => columnNames.contains(col.name)) })
      }
    
    }
    
    object TableEmpty extends Table(Seq.empty) {
      override def toString = "Table(Empty)"
    }
    
    object Table {
      def apply(rows: Row*) = new Table(rows)
    
      type Row = Array[Column]
    
      /**
       * Column representation. Note that each column has a name and a value. Since the class Table
       * is a sequence of rows which are a size-fixed array of columns, the name field is redundant
       * for Table. However, this column representation could be used in the future to support
       * schemata-less tables.
       */
      case class Column(name: String, value: String)
    
      private def parseLineTSV(line: String) = line.split("\t")
      private def writeLineTSV(line: Seq[String]) = line.mkString("", "\t", "\n")
    
      /**
       * It is assumed that the first row gives the names to the columns
       */
      def fromTSV(in: InputStream)(implicit encoding: Codec = Codec.UTF8): Table = {
        val linesIt = Source.fromInputStream(in).getLines
        if (linesIt.isEmpty) TableEmpty
        else {
          val columnNames = parseLineTSV(linesIt.next)
          val padding = {
            //add padding of empty columns-fields to lines that do not include last fields because they are empty
            def infinite[A](x: A): Stream[A] = x #:: infinite(x)
            infinite("")
          }
          val rows = linesIt.map { line =>
            ((0 until columnNames.size).zip(parseLineTSV(line) ++: padding).map { case (index, field) => Column(columnNames(index), field) }).toArray
          }.toStream
          new Table(rows)
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      在excel中写01-04而不是1-4..

      【讨论】:

        【解决方案4】:

        我在 excel 中有一个“文本”格式的单元格,其中填充了一个化学 casn,其值“8013-07-8”被重新格式化为日期格式。为了解决这个问题,我将一个单引号连接到值的开头,并在查看结果时正确呈现。当您单击单元格时,您会看到带前缀的单引号,但至少我不再将其视为日期。

        【讨论】:

          【解决方案5】:

          就我而言,当我在 D2 excel 单元格中输入 5-14 时,日期为 5 月 14 日。在某人的帮助下,我能够使用以下方法将日期格式更改为数字范围(5-14),并希望与您分享。 (我将以我的案例为例)。

          1. 在 Excel 中使用单元格格式,我将 D2(5 月 14 日)中的日期格式转换为数字优先(在我的情况下它给了我 43599)。
          2. 然后在 excel 中使用下面的公式将其转换为 5-14。 =IF(精确(D2,43599),“5-14”,D2)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-22
            • 1970-01-01
            • 1970-01-01
            • 2013-08-11
            • 1970-01-01
            • 2021-04-18
            • 1970-01-01
            相关资源
            最近更新 更多