2017-02-15 97 views
0

我有一個工作表,我在那裏添加500個超鏈接,這個過程大概需要90秒才能完成。我知道部分原因是因爲被迫使用Microsoft Interop Excel,部分原因是被迫使用for loop,但必須有一種更快/更高效的方式來實現此目標。這是我目前的語法優化添加超鏈接語法

public static void AddThatHyper() 
{ 
    long lr, i; 
    string cellVal; 
    WS = xlApp.ActiveWorkbook.ActiveSheet; 
    lr = WS.Cells[WS.Rows.Count, 2].End(Excel.XlDirection.xlUp).Row; 
    for (i = 2; i <= lr; i++) 
    { 
     Object Anchor = WS.Cells[i, 9]; 
     Object TextToDisplay = Convert.ToString(WS.Cells[i, 9]); 
     cellVal = WS.Cells[i, 1].Value; 
     cellVal = cellVal.Substring(0, Math.Min(28, cellVal.Length)); 
     rangeToHoldHyperlink = WS.Range["I" + i]; 

     if (cellVal.Contains("&") || 
      cellVal.Contains(",") || 
      cellVal.Contains("-") || 
      cellVal.Contains(".") 
      ) 
     { 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "CR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
     if (cellVal.Contains("'")) 
     { 
      cellVal = cellVal.Replace("'", "''"); 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "CR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
     else 
     { 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "FR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
    } 
} 

在這裏可以做些什麼來優化這個語法並使它在更快的時間框架內完成?

+0

問題是,您正試圖單獨讀取和寫入單元格。減少執行時間的最佳方法是將所有值作爲範圍讀取並將它們存儲在數組中。之後,您可以操作此設置,然後設置整個範圍的值。這樣可以減少程序所需的COM調用量。看看這個問題:http://stackoverflow.com/questions/6846958/optimized-way-of-adding-multiple-hyperlinks-in-excel-file-with-c-sharp?rq=1。 – Seunhaab

+0

@Seunhaab - 該選項可能有效,但我不清楚如何實現此目的。你能提供示例語法嗎?這些答案的URL設置與我的不同,因爲我有3種可能的URL應該如何的條件。 –

回答

0

請注意,此代碼未經測試。這是一個基於我之前製作的程序的例子。您可能必須進行一些手動調試才能查看值是否正確提取/轉換。

public static void AddThatHyper() 
{ 
    long lr, i; 
    string cellVal; 
    WS = xlApp.ActiveWorkbook.ActiveSheet; 
    lr = WS.Cells[WS.Rows.Count, 2].End(Excel.XlDirection.xlUp).Row; 
    string prefix = "";  

    string topCell = "I" + 2; 
    string bottomCell = "I" + lr; 

    //get_Range returns object array 
    Range range = ws.get_Range(topCell, bottomCell); 

    object[,] rangeValues = new object[lr - 2, 1]; 
    string[,] rangeStringValues = new string[lr - 2, 1]; 
    rangeValues = range.Cells.Formula; 

    //turn object array into string array 
    //should contain strings like "=hyperlink(url, text)" 
    for (int i = 0; i < rangeValues.GetLength(0); i++) 
    { 
     rangeStringValues[i, 0] = rangeValues[i, 0]?.ToString() ?? ""; 
    } 

    //edit hyperlinks 
    for (int i = 0; i < rangeStringValues.GetLength(0); i++) 
    { 
     prefix = "FR" 
     string hyperlink = rangeStringValues[i, 0]; 
     MatchCollection fields = Regex.Matches(hyperlink, @"("[A-Za-z0-9\.]*")"); 
     string url = fields[0]?.ToString() ?? ""; 
     string text = fields[1]?.ToString() ?? ""; 

     if (Regex.IsMatch(url, @"[&,\-\.]")) 
      prefix = "CR"; 
     else if (url.Contains("'")) 
     { 
      prefix = "CR" 
      url.Replace("'", "''"); 
     } 
     string formattedUrl = "'" + prefix + url + "'!A1"; 
     rangeStringValues[i, 0]= $"=HYPERLINK(""{formattedUrl }"", ""{text}"")"; 

    } 
    range.set_Value(value: values); 
    range.Formula = range.Value; 
}