代码之家  ›  专栏  ›  技术社区  ›  David Heffernan

如何在Excel中读取单元格的格式化文本表示

  •  3
  • David Heffernan  · 技术社区  · 14 年前

    我正在使用COM接口来Excel,我希望获得单元格的格式化文本表示,而不是真正的底层值。

    例如,假设单元格包含 1.23456 "1.2" . 我知道我可以用 Range.Text 范围.文本 也会因为限制为1024个字符而下降。

    另一个用例是当单元格计算为错误时,例如。 #DIV/0! , #NAME? , #REF! 等等,我知道我会读书 Range.Value 测试变量是否为类型 varError (我用的是Delphi,在VBA中应该是 vbError #DIV/0! 范围.文本 返回此值,但如果单元格隐藏或太窄则不返回。

    编辑

    3 回复  |  直到 11 年前
        1
  •  3
  •   Charles Williams    14 年前

    基于史蒂文的回答:试试这个VBA代码。
    由于排队要求,它不能正确地处理会计格式,但它不清楚在这种情况下您希望做什么。

        Sub testing()
        Dim oRng As Range
        Dim var As Variant
        Set oRng = Range("a3")
        If IsError(oRng) Then
            var = cstrError(oRng.Value)
        Else
        var = oRng.Value2
        If IsNumeric(var) Then var = Format(var, oRng.NumberFormatLocal)
        End If
        MsgBox Len(var) & " " & var
    End Sub
    Function cstrError(vError As Variant) As String
        Select Case CLng(vError)
        Case xlErrDiv0
            cstrError = "#DIV/0!"
        Case xlErrNA
            cstrError = "#N/A"
        Case xlErrName
            cstrError = "#NAME?"
        Case xlErrNull
            cstrError = "#NULL!"
        Case xlErrNum
            cstrError = "#NUM!"
        Case xlErrValue
            cstrError = "#VALUE!"
        Case xlErrRef
            cstrError = "#REF!"
        Case Else
            cstrError = "#N/A"
        End Select
    End Function
    
        2
  •  2
  •   Steven Rumbalski    14 年前

    要获取不包含错误的隐藏单元格的文本:

    Application.WorksheetFunction.Text(the_cell.Value, the_cell.NumberFormat)
    

    如果是个错误,这就失败了。因此,您可能需要首先检查:

    Application.WorksheetFunction.IsError(the_cell)
    

    不幸的是,很难找出你在 Error.Type

        3
  •  2
  •   David Heffernan    14 年前

    function GetCell(const Sheet: ExcelWorksheet; const Row, Col: Integer): string;
    
      function ErrorText(const Cell: ExcelRange; hr: HRESULT): string;
      const
        ErrorBase=HRESULT($800A0000);
      var
        i: Integer;
      begin
        Result := Cell.Text;
        for i := 1 to Length(Result) do begin
          if Result[i]<>'#' then begin
            exit;
          end;
        end;
        if hr=ErrorBase or xlErrDiv0 then begin
          Result := '#DIV/0!';
        end else if hr=ErrorBase or xlErrNA then begin
          Result := '#N/A';
        end else if hr=ErrorBase or xlErrName then begin
          Result := '#NAME?';
        end else if hr=ErrorBase or xlErrNull then begin
          Result := '#NULL!';
        end else if hr=ErrorBase or xlErrNum then begin
          Result := '#NUM!';
        end else if hr=ErrorBase or xlErrRef then begin
          Result := '#REF!';
        end else if hr=ErrorBase or xlErrValue then begin
          Result := '#VALUE!';
        end else begin
          Result := 'an error';
        end;
      end;
    
    var
      Cell: ExcelRange;
      hr: HRESULT;
    
    begin
      Cell := GetCellAsRange(Sheet, Row, Col);
      if VarIsError(Cell.Value, hr) then begin
        raise ECellValueError.CreateFmt(
          'Cell %s contains %s.',
          [R1C1toA1(Row,Col), ErrorText(Cell, hr)]
        );
      end else if VarIsNumeric(Cell.Value) then begin
        Result := Sheet.Application.WorksheetFunction.Text(Cell.Value, Cell.NumberFormatLocal);
      end else begin
        Result := ConvertToString(Cell.Value);
      end;
    end;