[英]How do I access programmatically the address of the copied selection from the clipboard
这是我要实现的目标:
用户复制一个单元格(或范围),例如A3,并且-按下按钮时-我需要以编程方式访问该单元格的地址(以创建链接)。
以文本格式访问剪贴板很容易:
string clip;
if (Clipboard.ContainsText()) clip = Clipboard.GetText();
我还发现可以像这样访问不同格式的剪贴板
var dataObj = Clipboard.GetDataObject();
var format = DataFormats.CommaSeparatedValue;
if (dataObj != null && dataObj.GetDataPresent(format))
{
var csvData = dataObj.GetData(format);
//...
}
但我终生无法找到哪种格式包含链接以及如何获取链接。 (我循环浏览了Clipboard.GetDataObject()。GetFormats()提供的所有格式,但是有些返回的我无法理解的难以理解的流。
背景信息:
答:链接必须存在,因为我可以使用“粘贴链接”来创建绝对引用
B.我正在使用Excel 2010和VS2010-Win7下的C#
C.代码在自定义任务窗格中运行
任何帮助表示赞赏!
所以,
并感谢所有设法阅读到此为止的人。 我终于弄明白了。 我的解决方案仍然很尴尬,因为我无法从剪贴板了解流的实际结构,但是我找到了我想要的东西:
protected override void WndProc(ref Message m)
{
const int WM_PASTE = 0x0302;
var enc = new System.Text.UTF7Encoding();
string buffer, rangeAddress;
if (m.Msg == WM_PASTE)
{
if (Clipboard.ContainsText())
{
string clip = Clipboard.GetText();
var dataObject = Clipboard.GetDataObject();
var mstream = (MemoryStream)dataObject.GetData("Link Source", true);
if(mstream == null) return;
var rdr = new System.IO.StreamReader(mstream, enc, true);
buffer = rdr.ReadToEnd();
buffer = StripWeirdChars(buffer);
int IndexExcl = buffer.IndexOf("!");
if (IndexExcl >= 0)
{
rangeAddress = buffer.Substring(IndexExcl + 1, buffer.Length - IndexExcl - 4);
// do whatever you want to do with it, e.g.:Globals.ThisAddIn.Application.ActiveCell.Value = rangeAddress;
return;
}
}
}
base.WndProc(ref m);
}
}
显然,这里的关键是GetData的特定格式:“链接源”。
读取结果流会产生一个字符串,其中包含许多奇怪的字符,但还会包含工作表名称和复制范围的坐标。 我用一个简单的方法剥离奇怪的字符
public static string StripWeirdChars(string source)
{
string res = "";
foreach (char c in source) if ((int)c >= 32) res += c;
return res;
}
仍然有一些我无法理解的奇怪字符,但是好消息是,在第一个感叹号之后,您会找到范围的地址(带有一些固定长度的尾随垃圾)。 即使该范围是从另一个工作表复制而来的,即使此工作表的名称中包含奇数字符(如德语变音符),也可以使用该方法。
肯定有一个更整洁的解决方案
通过IStream接口从剪贴板获取Excel Range对象
但是我发现那里的代码不完整(“明显的”部分被遗漏了),由于我的无能和一开始缺少IStream的经验,所以我无法正常工作。
感谢您使用此工具获得整洁的解决方案,但我对目前所拥有的感到满意。 多谢你们。
这只是@drdhk的答案,因为在其中一项评论中要求提供此答案以表明已回答:
所以,
并感谢所有设法阅读到此为止的人。 我终于弄明白了。 我的解决方案仍然很尴尬,因为我无法从剪贴板了解流的实际结构,但是我找到了我想要的东西:
protected override void WndProc(ref Message m)
{
const int WM_PASTE = 0x0302;
var enc = new System.Text.UTF7Encoding();
string buffer, rangeAddress;
if (m.Msg == WM_PASTE)
{
if (Clipboard.ContainsText())
{
string clip = Clipboard.GetText();
var dataObject = Clipboard.GetDataObject();
var mstream = (MemoryStream)dataObject.GetData("Link Source", true);
if(mstream == null) return;
var rdr = new System.IO.StreamReader(mstream, enc, true);
buffer = rdr.ReadToEnd();
buffer = StripWeirdChars(buffer);
int IndexExcl = buffer.IndexOf("!");
if (IndexExcl >= 0)
{
rangeAddress = buffer.Substring(IndexExcl + 1, buffer.Length - IndexExcl - 4);
// do whatever you want to do with it, e.g.:Globals.ThisAddIn.Application.ActiveCell.Value = rangeAddress;
return;
}
}
}
base.WndProc(ref m);
}
}
显然,这里的关键是GetData的特定格式:“链接源”。
读取结果流会产生一个字符串,其中包含许多奇怪的字符,但还会包含工作表名称和复制范围的坐标。 我用一个简单的方法剥离奇怪的字符
public static string StripWeirdChars(string source)
{
string res = "";
foreach (char c in source) if ((int)c >= 32) res += c;
return res;
}
仍然有一些我无法理解的奇怪字符,但是好消息是,在第一个感叹号之后,您会找到范围的地址(带有一些固定长度的尾随垃圾)。 即使该范围是从另一个工作表复制而来的,即使此工作表的名称中包含奇数字符(如德语变音符),也可以使用该方法。
肯定有一个更整洁的解决方案
通过IStream接口从剪贴板获取Excel Range对象:( http://www.codeproject.com/Articles/149009/Getting-the-Excel-Range-object-from-the-Clipboard )
但是我发现那里的代码不完整(“明显的”部分被遗漏了),由于我的无能和一开始缺少IStream的经验,所以我无法正常工作。
感谢您使用此工具获得整洁的解决方案,但我对目前所拥有的感到满意。 多谢你们。
您的方法有一个局限性:结果始终是矩形范围。 如果您已将A1:B2和A4:B5复制到剪贴板,则您的方法将返回A1:B5 ,这意味着第3行包含在结果范围中,实际上,它不属于该范围剪贴板。 有更多的剪贴板数据类型包含较少的怪异字符,例如ObjectLink或Link ,但它们对非矩形范围也有相同的限制。
在选择范围时,可以通过按Ctrl来选择非矩形范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.