[英]Submitting changes to excel file using Excel Interop in C#
I am still stuck in this code and bugs keep showing up.. I have excel file that is almost 24 columns, I am trying to adapt it to a 7 column excel file because the software I have works only on 7 columns and I don't want to re write the software from the beginning, so you will see some deletion and isertion of columns.. 我仍然停留在此代码中,并且错误不断出现。.我有将近24列的excel文件,我正尝试将其改编为7列的excel文件,因为我拥有的软件只能在7列上工作,而我却没有想要从一开始就重新编写软件,因此您将看到一些列的删除和散列。
I have 5 columns inside this excel file that have either "x" value or null. 我在这个excel文件中有5列,这些列具有“ x”值或null。
what I am trying to do is to create a new column between range A1,and B1 that is called category, so if there is an x in column 5, i write E in the category field, else if the x is in the 6th column then I write P in the category column.. and so on. 我想做的是在范围A1和B1之间创建一个称为类别的新列,因此,如果第5列中有x,则在类别字段中写E,否则,如果x在第6列中然后我在类别列中写P。依此类推。 And then I need to delete these 5 columns that I no longer need (Range E1:I1)
然后我需要删除不再需要的这5列(范围E1:I1)
The problem is when I debug the code, I can see that the values[,] have the column inserted, and the values has been transfered correctly, but when the temp_data.csv is produced, it has the new excel file after deletion so now it contains 11 columns, but the new Category column together with the values are not there... 问题是当我调试代码时,我可以看到values [,]插入了列,并且值已正确传输,但是当生成temp_data.csv时,删除后它具有新的excel文件,所以现在它包含11列,但是新的Category列及其值不存在...
Microsoft.Office.Interop.Excel.Workbook workbook = xl.Workbooks.Open(p_sUBKPath, Type.Missing, false, 4, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range range = ws.UsedRange;
// delete columns that we don't need from the new excel file
Microsoft.Office.Interop.Excel.Range range2 = ws.get_Range("A1","A1");
range2.EntireColumn.Delete();
Microsoft.Office.Interop.Excel.Range range3 = ws.get_Range("B1", "B1");
range3.EntireColumn.Delete();
Microsoft.Office.Interop.Excel.Range range4 = ws.get_Range("D1", "L1");
range4.EntireColumn.Delete();
Microsoft.Office.Interop.Excel.Range range5 = ws.get_Range("I1", "M1");
range5.EntireColumn.Delete();
Microsoft.Office.Interop.Excel.Range range6 = ws.get_Range("K1", "K1");
range6.EntireColumn.Delete();
//insert a new column ( Category)
Microsoft.Office.Interop.Excel.Range range7 = ws.get_Range("B1", "B1");
range7.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
object[,] tempVal = (object[,])range.Value2;
tempVal[1, 2] = (object)"Category";
for (int row = 2; row <= tempVal.GetUpperBound(0); row++)
{
try
{
if ((!String.IsNullOrEmpty((string)tempVal[row, 5])) && (string)tempVal[row, 5] == "x")
{
tempVal[row, 2] = (string)"E";
}
else if ((!String.IsNullOrEmpty((string)tempVal[row, 6])) && (string)tempVal[row, 6] == "x")
{
tempVal[row, 2] = (string)"P";
}
else if ((!String.IsNullOrEmpty((string)tempVal[row, 7])) && (string)tempVal[row, 7] == "x")
{
tempVal[row, 2] = (string)"Phy";
}
else if ((!String.IsNullOrEmpty((string)tempVal[row, 8])) && (string)tempVal[row, 8] == "x")
{
tempVal[row, 2] = (string)"L";
}
else if ((!String.IsNullOrEmpty(tempVal[row, 9].ToString())) && (string)tempVal[row, 9] == "x")
{
tempVal[row, 2] = (string)"Ex";
}
else
MessageBox.Show("unknow");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
object[,] values = tempVal;
if (Convert.ToString(values[1, 1]).ToUpper().Trim() == "SHORT NAME" && Convert.ToString(values[1, 2]).ToUpper().Trim() == "CATEGORY" && Convert.ToString(values[1, 3]).ToUpper().Trim() == "LONG NAME EN" && Convert.ToString(values[1, 4]).ToUpper().Trim() == "LONG NAME DE" && Convert.ToString(values[1, 5]).ToUpper().Trim() == "ELEMENT" && Convert.ToString(values[1, 6]).ToUpper().Trim() == "PROPERNAME" && Convert.ToString(values[1, 7]).ToUpper().Trim() == "PHYSICAL" && Convert.ToString(values[1, 8]).ToUpper().Trim() == "LOGICAL" && Convert.ToString(values[1, 9]).ToUpper().Trim() == "EXTENSION" && Convert.ToString(values[1, 10]).ToUpper().Trim() == "CREATED BY" && Convert.ToString(values[1, 11]).ToUpper().Trim() == "CREATED ON" && Convert.ToString(values[1, 12]).ToUpper().Trim() == "STATE")
{
for (int row = 1; row <= values.GetUpperBound(0); row++)
for (int col = 1; col <= values.GetUpperBound(1); col++)
{
string value = Convert.ToString(values[row, col]);
if (value.Contains(","))
{
range.Cells.set_Item(row, col, value.Replace(",", p_sPsuedostring));
}
if (value.Contains(" "))
{
range.Cells.set_Item(row, col, value.Replace(" ", p_sPsuedostring + " " + p_sPsuedostring));
}
}
if (File.Exists(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv"))
File.Delete(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv");
//Save the Latest databse as Data_Temp.csv
ws.SaveAs(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlUnicodeText, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
xl.DisplayAlerts = true;
try
{
xl.Workbooks[1].Close(false, Type.Missing, Type.Missing);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
xl.Application.Quit();
xl.Quit();
l_bClosedSuccessfully = true;
Based on your above comments, let's say your Excel File looks like this. 根据上述意见,假设您的Excel文件如下所示。 I have colored the columns Yellow which needs to be deleted.
我已将需要删除的列涂成黄色。
Screenshot : 屏幕截图 :
Logic : 逻辑 :
usedrange
. usedrange
。 UsedRange
can also include unnecessary rows/columns making your code slower. UsedRange
还可以包含不必要的行/列,从而使您的代码变慢。 I am finding the last cell which has data and then using it's .Row
and .Column
property to construct my range which contains "X" .Row
和.Column
属性构造包含“ X”的范围 .Find
and . .Find
和。 Findnext
to search for "X" in your range. Findnext
在您的范围内搜索“ X”。 Once you find that, get th found cell's column number and subtract 2 from it. IF
condition to check what is the value of the Column after you subtract 2 from it and then decide on the keyword
that you want to use. keyword
之后,只需使用IF
条件来检查Column的值是什么。 Code : 代码 :
Try this code (TRIED AND TESTED) 尝试此代码(已尝试并已测试)
using System;
using System.Windows.Forms;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
Namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlexcel;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range Rng, aCell, bCell;
String sMsg = "";
object misValue = Missing.Value;
xlexcel = new Excel.Application();
xlexcel.Visible = true;
//~~> Open a File (Chnage filename as applicable)
xlWorkBook = xlexcel.Workbooks.Open("C:\\MyFile.xlsx",
0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
"\t", false, false, 0, true, 1, 0);
//~~> Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//~~> Delete relevant columns in reverse order
//A,c,f,g,h,i,j,k,l,m,n,t,u,v,w,x,AA
xlWorkSheet.get_Range("AA1", "AA1").EntireColumn.Delete();
xlWorkSheet.get_Range("T1", "X1").EntireColumn.Delete();
xlWorkSheet.get_Range("F1", "N1").EntireColumn.Delete();
xlWorkSheet.get_Range("C1", "C1").EntireColumn.Delete();
xlWorkSheet.get_Range("A1", "A1").EntireColumn.Delete();
//~~> Insert the Category Column
xlWorkSheet.get_Range("B1", "B1").EntireColumn.Insert(
Excel.XlInsertShiftDirection.xlShiftToRight);
//~~> get the last row and the last column of your data range
//~~> This is much better than using usedrange which might
//'~~> include unnecessary ranges
int lRow = xlWorkSheet.Cells.SpecialCells(
Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Row;
int lCol = xlWorkSheet.Cells.SpecialCells(
Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Column;
String Addr = xlWorkSheet.Cells[1, lCol].Address;
//~~> This is to get the column name from column number
String ColName = Addr.Split('$')[1];
//~~> This is your data range. I am assuming that Row 1 has headers
Rng = xlWorkSheet.get_Range("C2:" + ColName + lRow, misValue);
//~~> Find the first occurance of "X"
aCell = Rng.Find("X",misValue,Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlWhole,misValue,
Excel.XlSearchDirection.xlNext,misValue,misValue,misValue);
//~~> Find the next occurance of "X" using FindNext
if(aCell != null)
{
//~~> Get the column number and subtract 2 from it
int col = aCell.Column-2;
//~~> Choose the relevant keyword
if (col == 1)
{
sMsg = "Element";
}
else if (col == 2)
{
sMsg = "propername";
}
else if (col == 3)
{
sMsg = "physical";
}
else if (col == 4)
{
sMsg = "logical";
}
else if (col == 5)
{
sMsg = "extension";
}
//~~> Populate the Category Column
xlWorkSheet.Cells[aCell.Row, 2].Value = sMsg;
string sFirstFoundAddress = aCell.get_Address(true, true,
Excel.XlReferenceStyle.xlA1, misValue, misValue);
bCell = Rng.Cells.FindNext(aCell);
string sAddress = bCell.get_Address(true, true,
Excel.XlReferenceStyle.xlA1, misValue, misValue);
//~~> FindNext until the first found cell is found again
While (!sAddress.Equals(sFirstFoundAddress))
{
//~~> Get the column number and subtract 2 from it
col = bCell.Column-2;
//~~> Choose the relevant keyword
if (col == 1)
{
sMsg = "Element";
}
else if (col == 2)
{
sMsg = "propername";
}
else if (col == 3)
{
sMsg = "physical";
}
else if (col == 4)
{
sMsg = "logical";
}
else if (col == 5)
{
sMsg = "extension";
}
xlWorkSheet.Cells[bCell.Row, 2].Value = sMsg;
bCell = Rng.Cells.FindNext(bCell);
sAddress = bCell.get_Address(true, true,
Excel.XlReferenceStyle.xlA1, misValue, misValue);
}
}
//~~> Once done close and quit Excel
xlWorkBook.Close(true, misValue, misValue);
xlexcel.Quit();
//~~> CleanUp
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlexcel);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}
ScreenShot (After the code is run): 屏幕截图 (运行代码后):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.