从单元格复制时请省略引号

116

问题
从Excel复制单元格到程序外部时,双引号会自动添加。

细节
我正在Windows 7电脑上使用Excel 2007。如果我的单元格包含以下公式:

="1"&CHAR(9)&"SOME NOTES FOR LINE 1."&CHAR(9)&"2"&CHAR(9)&"SOME NOTES FOR LINE 2."

在 Excel 中,单元格中的输出(格式为数字)看起来像这样:

1SOME NOTES FOR LINE 1.2SOME NOTES FOR LINE 2.

好的。但是,如果我将该单元格复制到另一个程序(比如记事本),开头和结尾会出现烦人的双引号。需要注意的是,由 "CHAR(9)" 创建的制表符被保留了下来,这是好的。

"1  SOME NOTES FOR LINE 1.  2     SOME NOTES FOR LINE 2."

当我将其复制到另一个程序时,如何避免这些双引号出现?换句话说,当单元格被复制到剪贴板时,我能否防止自动添加这些引号?


1
@McAdam331 很不幸,我需要它完全按照我在这里写的方式工作,减去前导和尾随的双引号。请不要让制表符分散这个问题的重点 - 它们必须存在。 - Aaron Thomas
我注意到有人投票关闭了这个问题。如果有关系的话,我仍然在关注这个问题,看是否有适当的答案出现。我自己还没有找到符合问题的解决方案,但我会继续寻找可行的方法。 - Aaron Thomas
我从来没有想明白这个问题。我记得为此尝试了很长时间。你考虑过在这个问题上发起悬赏吗? - AdamMc331
这似乎是superuser上的一个问题的副本:http://superuser.com/questions/324271/how-to-copy-multi-line-text-from-excel-without-quotes 我不是专家,所以不知道这是否意味着它需要标记。 - Kit Johnson
请参考此答案了解原因和解决方法:https://dev59.com/zWAf5IYBdhLWcg3wMwXX#60251126 - spioter
显示剩余5条评论
16个回答

121

我刚遇到过这个问题,将每个单元格使用CLEAN函数进行包装后,问题就得到了解决。通过执行=CLEAN(,选择你的单元格,然后自动填充整个列即可相对容易地实现此操作。在我这样做之后,粘贴到记事本或其他程序中的文本不再出现重复引号。


31
删除多余引号的答案很好,但不幸的是它也会删除制表符...而在问题中,我想保留它们。感谢您的回答! - Aaron Thomas
28
它会移除所有ASCII字符,包括小于32的字符,因此也包括换行符。 - NeplatnyUdaj
2
这是真正的答案。 - Tyler Murry
20
这不是一个好的解决方案,因为它会移除所有特殊字符。 - user1945782
1
你是我的救星。我没想到这种方法会奏效,但如果这不完美地运行,那我就该死了。 - 1owk3y
显示剩余4条评论

41

如果您尝试将内容粘贴到Word-Pad、Notepad++或Word中,您将不会遇到此问题。要复制单元格值作为纯文本,以实现您的描述,您需要使用宏:

在您希望应用此方法的工作簿中(或者在Personal.xls中,如果您希望在几个工作簿中使用),请将以下代码放置在标准模块中:

代码:

Sub CopyCellContents()
'create a reference in the VBE to Microsft Forms 2.0 Lib
' do this by (in VBA editor) clicking tools - > references and then ticking "Microsoft Forms 2.0 Library"
Dim objData As New DataObject
Dim strTemp As String
strTemp = ActiveCell.Value
objData.SetText (strTemp)
objData.PutInClipboard
End Sub

要向项目(工作簿)添加标准模块,请使用Alt+F11打开VBE,然后在左上方的项目窗口中右键单击您的工作簿,并选择插入>模块。将代码粘贴到右侧将打开的代码模块窗口中。

回到Excel,选择Tools>Macro>Macros,然后选择名为“CopyCellContents”的宏,然后从对话框中选择选项。在这里,您可以为宏分配一个快捷键(例如,像普通复制一样使用CTRL+C),我使用了CTRL+Q

然后,当您想要将单个单元格复制到记事本/任何位置时,只需按Ctrl+q(或您选择的其他键)然后按CTRL+V或Edit>Paste即可将其粘贴到所选目标中。

我的答案是从这里复制的(加了一些内容):here

编辑:(来自评论)

如果您在参考列表中找不到Microsoft Forms 2.0库,则可以尝试

  • 寻找FM20.DLL(感谢@Peter Smallwood)
  • 点击浏览并选择C:\Windows\System32\FM20.dll(32位Windows)(感谢@JWhy)
  • 点击浏览并选择C:\Windows\SysWOW64\FM20.dll(对于64位)

1
看起来VBA是唯一的解决方案 - 感谢您的建议。 - Aaron Thomas
1
如果您在引用列表中看不到Microsoft Forms库,则请浏览FM20.DLL。 - Peter Smallwood
19
如果我将其粘贴到Notepad ++中,我仍然可以获得报价。 - Kat
1
你的第一句话不准确。在Word中,粘贴(保留纯文本)会保留引号。而且正如其他人指出的那样,在Notepad++中粘贴也会产生引号。 - Tony
3
更新的版本可能已经改变了这种行为,但是截至本评论发布日期,Word和Notepad++的当前版本在单个或多个单元格选择时都会粘贴这些引号。 - Tony
显示剩余9条评论

35

首先将其粘贴到Word中,然后您可以将其粘贴到记事本中,它将出现而不带引号


谢谢您的回答,但我不能将其标记为好的解决方案。此外,它是一个重复的解决方案,已经在此问题中提供,见https://dev59.com/zWAf5IYBdhLWcg3wMwXX#24913557。 - Aaron Thomas
4
谢谢,我喜欢这个解决方案。快速简单。 - Bajal
点赞这个...在我的情况下,我的问题是,对于我收到的特定类型的请求,数据以Excel文件的形式出现,我需要将其粘贴到纯文本框中。当我这样做时,我会得到引号。我曾经使用文本编辑器删除了额外的引号(它也引用了引号..很烦人!)。寻找一个简单的解决方案,我发现先将其粘贴到Word中可以去掉多余的引号。希望我能点赞10次 :) - Carnix
这将删除制表符。至少在使用Word时是这样,不确定在WordPad中是否也适用。 - Matthew Lueder
这仍然是目前最佳的解决方案。 - zygimantus
@zygimantus 今天也一样! - Jithin P Gopal

10
如果您想选择多个单元格并将其值复制到剪贴板,而不带有所有那些烦人的引号,下面的代码可能会有所帮助。这是对用户3616725上面提供的代码的增强。
Sub CopyCells()
 'Attach Microsoft Forms 2.0 Library: tools\references\Browse\FM20.DLL
 'Then set a keyboard shortcut to the CopyCells Macro (eg Crtl T)
 Dim objData As New DataObject
 Dim cell As Object
 Dim concat As String
 Dim cellValue As String
 CR = ""
  For Each cell In Selection
  If IsNumeric(cell.Value) Then
   cellValue = LTrim(Str(cell.Value))
  Else
   cellValue = cell.Value
  End If
  concat = concat + CR + cellValue
  CR = Chr(13)
 Next
 objData.SetText (concat)
 objData.PutInClipboard
End Sub

我认为这是目前为止最好的答案。 - posfan12
2
基于这个答案,看一下我的回答,修复以下的错误:
  1. 将空单元格转换为空字符串而不是“0”。
  2. 在每个单元格之后追加制表符(ASCII 9)而不是回车符(ASCII 13)。
  3. 在每行结束时追加回车符(ASCII 13)+ 换行符(ASCII 10)(与回车符(ASCII 13)相比)。
注意:您仍然无法复制嵌入在单元格中的字符,因为这会导致将该单元格粘贴到目标字段时退出(即在 Access 或 SSMS 的编辑表窗口中粘贴时出现 Tab 或 CR)。
- Tom
还修复了“变量未定义”编译器错误(针对“CR”变量)。 - Tom

5
如果你想选择多个单元格并将它们的值复制到剪贴板上,而不会出现所有那些烦人的引号(没有 Peter Smallwood 的多个单元格解决方案中的错误),下面的代码可能有用。这是对Peter Smallwood的代码进行改进(其“是对user3616725提供的代码的改进”)。它修复了Peter Smallwood的解决方案中的以下错误:
  • 避免“变量未定义”的编译器错误(在此处为“CR” - “clibboardFieldDelimiter”)
  • 将空单元格转换为空字符串而不是“0”。
  • 在每个单元格后添加制表符(ASCII 9)而不是回车(ASCII 13)。
  • 在每一行后附加一个回车(ASCII 13)+ 换行(ASCII 10)(与CR(ASCII 13)相比)。

注意:你仍然不能复制嵌入在单元格内的字符,否则会导致你粘贴该单元格时退出目标字段(即在Access或SSMS的编辑表窗口中粘贴Tab或CR)。


Option Explicit

Sub CopyCellsWithoutAddingQuotes()

' -- Attach Microsoft Forms 2.0 Library: tools\references\Browse\FM20.DLL
' -- NOTE: You may have to temporarily insert a UserForm into your VBAProject for it to show up.
' -- Then set a Keyboard Shortcut to the "CopyCellsWithoutAddingQuotes" Macro (i.e. Crtl+E)

Dim clibboardFieldDelimiter As String
Dim clibboardLineDelimiter As String
Dim row As Range
Dim cell As Range
Dim cellValueText As String
Dim clipboardText As String
Dim isFirstRow As Boolean
Dim isFirstCellOfRow As Boolean
Dim dataObj As New dataObject

clibboardFieldDelimiter = Chr(9)
clibboardLineDelimiter = Chr(13) + Chr(10)
isFirstRow = True
isFirstCellOfRow = True

For Each row In Selection.Rows

    If Not isFirstRow Then
        clipboardText = clipboardText + clibboardLineDelimiter
    End If

    For Each cell In row.Cells

        If IsEmpty(cell.Value) Then

            cellValueText = ""

        ElseIf IsNumeric(cell.Value) Then

            cellValueText = LTrim(Str(cell.Value))

        Else

            cellValueText = cell.Value

        End If ' -- Else Non-empty Non-numeric

        If isFirstCellOfRow Then

            clipboardText = clipboardText + cellValueText
            isFirstCellOfRow = False

        Else ' -- Not (isFirstCellOfRow)

            clipboardText = clipboardText + clibboardFieldDelimiter + cellValueText

        End If ' -- Else Not (isFirstCellOfRow)

    Next cell

    isFirstRow = False
    isFirstCellOfRow = True

Next row

clipboardText = clipboardText + clibboardLineDelimiter

dataObj.SetText (clipboardText)
dataObj.PutInClipboard

End Sub

4

当我遇到引号问题时,我的解决方法是从单元格文本末尾删除回车符。由于这些回车符(由外部程序插入),Excel会将引号添加到整个字符串中。


4
引号也可能是公式内部的CR/LF(不一定在结尾),或者像这个帖子中的原始问题一样是制表符(char(9))。 - Turbo
你真的让我的生活变得轻松了。 - Sracanis

3

与“user3616725”的答案相关的可能问题:
我在使用Windows 8.1,与“user3616725”所接受的答案中链接的VBA代码似乎存在问题:

Sub CopyCellContents()
 ' !!! IMPORTANT !!!:
 ' CREATE A REFERENCE IN THE VBE TO "Microsft Forms 2.0 Library" OR "Microsft Forms 2.0 Object Library"
 ' DO THIS BY (IN VBA EDITOR) CLICKING TOOLS -> REFERENCES & THEN TICKING "Microsoft Forms 2.0 Library" OR "Microsft Forms 2.0 Object Library"
 Dim objData As New DataObject
 Dim strTemp As String
 strTemp = ActiveCell.Value
 objData.SetText (strTemp)
 objData.PutInClipboard
End Sub

详细信息:
运行上述代码并将剪贴板粘贴到Excel单元格中,我得到了两个由方块组成的符号,内部有一个问号,就像这样:⍰⍰。在记事本中粘贴甚至什么也不显示。

解决方法:
经过一段时间的搜索,我找到了用户“Nepumuk”发布的另一个使用Windows API的VBA脚本。这是他的代码,最终对我起作用了:

Option Explicit

Private Declare Function OpenClipboard Lib "user32.dll" ( _
    ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
Private Declare Function SetClipboardData Lib "user32.dll" ( _
    ByVal wFormat As Long, _
    ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32.dll" ( _
    ByVal wFlags As Long, _
    ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32.dll" ( _
    ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32.dll" ( _
    ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32.dll" ( _
    ByVal hMem As Long) As Long
Private Declare Function lstrcpy Lib "kernel32.dll" ( _
    ByVal lpStr1 As Any, _
    ByVal lpStr2 As Any) As Long

Private Const CF_TEXT As Long = 1&

Private Const GMEM_MOVEABLE As Long = 2

Public Sub Beispiel()
    Call StringToClipboard("Hallo ...")
End Sub

Private Sub StringToClipboard(strText As String)
    Dim lngIdentifier As Long, lngPointer As Long
    lngIdentifier = GlobalAlloc(GMEM_MOVEABLE, Len(strText) + 1)
    lngPointer = GlobalLock(lngIdentifier)
    Call lstrcpy(ByVal lngPointer, strText)
    Call GlobalUnlock(lngIdentifier)
    Call OpenClipboard(0&)
    Call EmptyClipboard
    Call SetClipboardData(CF_TEXT, lngIdentifier)
    Call CloseClipboard
    Call GlobalFree(lngIdentifier)
End Sub

要像上面的第一段VBA代码一样使用它,只需更改子程序“Beispiel()”:

Public Sub Beispiel()
    Call StringToClipboard("Hallo ...")
End Sub

致:

Sub CopyCellContents()
    Call StringToClipboard(ActiveCell.Value)
End Sub

并按照"用户3616725"所建议的方法通过Excel宏菜单运行它:

回到Excel,选择工具>宏>宏,然后选择名为“CopyCellContents”的宏,再从对话框中选择选项。在这里,您可以将宏分配给快捷键(例如像正常复制的Ctrl+c) - 我使用了Ctrl+q。

然后,当您想要将单个单元格复制到记事本/任何位置时,只需按Ctrl+q(或您选择的其他键),然后在所选目标中进行Ctrl+v或编辑>粘贴。


编辑(2015年11月21日):
@来自“dotctor”的评论:
不,这不是一个新问题!我认为这是对接受答案时可能遇到的问题的很好补充。如果我有更多的声望,我会创建一个评论。
@来自“Teepeemm”的评论:
是的,你是对的,“问题:”开头的答案是误导人的。改为:“与“用户3616725”的答案相关的可能问题”。作为评论,我肯定会写得更紧凑。


我认为这是一个有效的答案(尽管以“问题”开头似乎表明您有一个新问题)。而且评论限制在600个字符,所以这肯定太长了。 - Teepeemm
太棒了!谢谢!唯一的问题似乎是它只适用于单个单元格。是否可以进行改进,以允许复制范围? - NeplatnyUdaj

2
注意:引号的原因是,当数据从Excel移动到剪贴板时,它完全符合CSV标准,这包括引用包含制表符、换行符等值(双引号字符被替换为两个双引号字符)。
因此,另一种方法,特别是在OP的情况下,当制表符/换行符由公式引起时,可以使用替代字符来代替制表符和硬回车。我使用ASCII单元分隔符=char(31)代替制表符和ASCII记录分隔符=char(30)代替换行符。
然后将其粘贴到文本编辑器中将不涉及额外的CSV规则,并且您可以快速搜索和替换以再次将它们转换回来。
如果制表符/换行符嵌入在数据中,则可以在Excel中进行搜索和替换以将它们转换。
无论是使用公式还是更改数据,选择分隔符的关键是永远不要使用实际数据中可能存在的字符。这就是为什么我推荐使用低级ASCII字符的原因。

这很有用 - 我没有想过这种方法,但是使用搜索/替换将MYCHAR转换回换行符比试图清理Excel引起的引号混乱要容易得多。谢谢! - caponica

2
更简单的方法:
首先将内容粘贴到一封新的草稿邮件中 - 不会包含任何引号。
然后使用Ctrl-A选中并从此处再次复制,丢弃草稿邮件即可。

这几乎完美地运作了;单元格之间的换行符也丢失了,这可能是期望的行为,但不适用于我的情况。 - VeraKozya

1
为了在记事本中保留换行符,请在宏中替换此行:
strTemp = ActiveCell.Value

通过:

strTemp = Replace(ActiveCell.Value, Chr(10), vbCrLf)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接