2014-10-20 96 views
1

這裏訪問程序的拷貝選擇的地址就是我想要實現:我如何從剪貼板

用戶複製單元格(或範圍),說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(),但有些高深莫測返回溪流我不能讓感

背景資料:。

A.鏈路必須在那裏,因爲我可以使用「粘貼鏈接」,它創建了一個絕對的參考

B.我使用Excel 2010和VS2010 - C#的Win7

下的代碼在一個自定義任務窗格

任何運行幫助讚賞!


所以,

,並感謝大家誰管理,直到讀了這一點。我終於弄明白了。我的解決方案仍然是尷尬的,因爲我不能讓我的周圍將剪貼板中的數據流的實際結構的頭,但我發現我在尋找:

 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; 
     } 

仍然有一些奇怪的字符,我不能做的意義,但好消息是,第一個感嘆號之後,你會發現範圍的地址(與一些固定長度的尾隨垃圾)。即使該範圍是從其他工作表複製的,並且即使該工作表的名稱中包含奇怪的字符(如德語元音變音符號),也可以工作。

當然是有一個非常巧妙的解決方案在那裏

Getting the Excel Range object from the Clipboard through the IStream interface

但我發現有不完整的代碼(「明顯」的部分被排除在外),我無法得到的東西由於我的無能和缺乏IStream的經驗而開始工作。

任何幫助使用這個來得到一個整潔的解決方案是讚賞,但我滿足於我目前所擁有的。多謝你們。

+0

僅供參考您目前無法使用C#代碼創建堆棧片段。 – 2014-10-20 19:50:46

+0

你爲什麼要訪問剪貼板而不是Interop.Excel.Range? – 2014-10-21 07:18:21

+0

@ vba4all:我的理想場景是拖放:用戶將一個單元格拖到目標字段。因爲這似乎不可能(對嗎?)我用「明顯的」下一個解決方案,複製和粘貼。至於訪問Interop.Excel.Range,我沒有看到這對我有什麼幫助。我假設如果複製它,剪貼板將保存範圍對象。從這裏我可以得到地址,但是我的問題是,我無法在剪貼板中獲得範圍:-( – drdhk 2014-10-21 09:58:56

回答

0

這是剛剛從@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; 
    } 

仍然有一些奇怪的字符,我不能做的意義,但好消息是,第一個感嘆號之後,你會發現範圍的地址(與一些固定長度的尾隨垃圾)。即使該範圍是從其他工作表複製的,並且即使該工作表的名稱中包含奇怪的字符(如德語元音變音符號),也可以工作。

當然是有一個非常巧妙的解決方案在那裏

獲取剪貼板中的Excel Range對象通過IStream接口: (http://www.codeproject.com/Articles/149009/Getting-the-Excel-Range-object-from-the-Clipboard

但我發現代碼中有不完整(以下簡稱「明顯的「部分被遺漏了),由於我的無能和缺乏IStream的經驗,我無法讓這個東西工作。

任何幫助使用這個來得到一個整潔的解決方案是讚賞,但我滿足於我目前所擁有的。多謝你們。

0

你的方法有一個限制:結果總是一個矩形範圍。如果您已經複製,讓我們說A1:B2A4:B5到剪貼板,你的方法將返回A1:B5,這意味着該行包括在結果範圍內,在事實上,它不是剪貼板中的範圍的一部分。 還有更多包含較少奇怪字符的剪貼板數據類型,如ObjectLink鏈接,但它們對於非矩形範圍具有相同的限制。

非矩形範圍可以通過在選擇範圍時按Ctrl來選擇。