C#-Microsoft.Office.Interop.Excel将特定行从一个Excel复制到另一个Excel实例,然后删除该行

问题描述

我要实现的目标是,基于电子邮件验证,将整个行从一个excel实例复制到另一个excel实例,然后再删除该行。事实是,此时我的方法(复制行并删除行)都不起作用,由于某种原因,一旦我运行代码,两个文件都变成read only

很抱歉犯了任何错误,但这是我在这里的第一个问题。

您是否发现关于我的代码的任何错误?或者您能解释一下它的外观吗?

这是我到目前为止尝试过的:

using Microsoft.Office.Interop.Excel;
using System;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace CleanUpUserList
{
    public class Program
    {

        static Regex ValidEmailRegex = CreateValidEmailRegex();
        private static string invalidUserFileName = @"C:\Users\Sebastian Cocirla\Desktop\To.xlsx";
        private static string validUserFileName = @"C:\Users\Sebastian Cocirla\Desktop\From.xlsx";
        private static string saveAsFileName = "SSO Member List NON SECUtix - INValid.xlsx";
        private static string mailToMatchForInvalidation = "mailinator";
        private static char mailSeparator = '@';
        private static char domainSeparator = '.';

        static void Main()
        {
            CleanUpExcelFile();
        }

        public static void CleanUpExcelFile()
        {
            int newWorkbookIndex = 0;

            Application app = new Application();

            Workbook validUserFile = app.Workbooks.Open(validUserFileName);
            Worksheet validUserWorksheet = validUserFile.Sheets[1];

            Workbook invalidUserFile = app.Workbooks.Open(invalidUserFileName);
            Worksheet invalidUserWorksheet = invalidUserFile.Sheets[1];

            Range range = validUserWorksheet.UsedRange;

            int rows = range.Rows.Count;

            validUserWorksheet.Activate();
            invalidUserWorksheet.Activate();

            for (int rowIndex = 2; rowIndex < rows; rowIndex++)
            {

                var emailAddress = range.Cells[rowIndex,8].Value2.ToString();

                if (!EmailIsValid(emailAddress))
                {
                    newWorkbookIndex++;

                    copyRow(validUserFile,invalidUserFile,validUserWorksheet,invalidUserWorksheet,rowIndex,newWorkbookIndex);

                    ((Range)validUserWorksheet.Rows[rowIndex]).Delete(XlDeleteShiftDirection.xlShiftUp);
                }
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();

            Marshal.ReleaseComObject(range);
            Marshal.ReleaseComObject(validUserWorksheet);
            Marshal.ReleaseComObject(invalidUserWorksheet);

            validUserFile.Close();
            invalidUserFile.Close();
            Marshal.ReleaseComObject(validUserFile);
            Marshal.ReleaseComObject(invalidUserFile);

            app.Quit();
            Marshal.ReleaseComObject(app);
        }

        private static void copyRow(Workbook validUserFile,Workbook invalidUserFile,Worksheet validUserWorksheet,Worksheet invalidUserWorksheet,int rowIndex,int newWorkbookIndex)
        {

            var selectedRow = validUserWorksheet.Range["A1:M1"];
            var destinationRow = invalidUserWorksheet.Range["A2:M2"];

            selectedRow.copy(destinationRow);
            validUserFile.Save();
            invalidUserFile.Save();
        }

        private static Regex CreateValidEmailRegex()
        {
            string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                                       + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                                       + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

            return new Regex(validEmailPattern,RegexOptions.IgnoreCase);
        }

        private static bool EmailIsValid(string emailAddress)
        {
            var splitEmailHost = emailAddress.Split(mailSeparator);
            var hostLength = splitEmailHost[1].Split(domainSeparator)[0].Length;

            bool isValid = ValidEmailRegex.IsMatch(emailAddress)
                           && !splitEmailHost[1].Contains(mailToMatchForInvalidation)
                           && hostLength > 1;

            return isValid;
        }

    }
}

任何帮助将不胜感激!

解决方法

您可以得到一个特定的行,例如

Excel.Range range = workSheet.get_Range("A1","A1").EntireRow;

并使用以下语句将其删除。

range.Delete();

然后使用foreach语句遍历它并将其保存到另一个Excel文件中。

foreach (var i in range.Value)
{
    if (i != null)
        workSheet2.Cells[rowindex,columnindex++].Value = i;
}

这是一个简单的演示。

// open excel1 and get specific row
Excel.Application excel = new Excel.Application();
Excel.Workbook workBook = excel.Workbooks.Open(@"D:\test.xlsx",ReadOnly: false,Editable: true);
Excel.Worksheet workSheet = workBook.Worksheets.Item[1] as Excel.Worksheet;
if (workSheet == null)
    return;
Excel.Range range = workSheet.get_Range("A1","A1").EntireRow;

// open excel2
Excel.Application excel2 = new Excel.Application();
Excel.Workbook workBook2 = excel2.Workbooks.Open(@"D:\new.xlsx",Editable: true);
Excel.Worksheet workSheet2 = workBook2.Worksheets.Item[1] as Excel.Worksheet;
if (workSheet2 == null)
    return;

int rowindex = 12; // here is the rowindex that copy to
int columnindex = 1;

foreach (var i in range.Value)
{
    if (i != null)
        workSheet2.Cells[rowindex,columnindex++].Value = i;
}

range.Delete(); // delete the row

// save and close excel
excel.Application.ActiveWorkbook.Save();
excel.Application.Quit();
excel.Quit();

excel2.Application.ActiveWorkbook.Save();
excel2.Application.Quit();
excel2.Quit();
,

只需快速阅读您的代码

var selectedRow = validUserWorksheet.Range["A1:M1"];
var destinationRow = invalidUserWorksheet.Range["A2:M2"];

为什么不

var selectedRow = validUserWorksheet.Range["A" + rowIndex + ":M" + rowIndex];
var destinationRow = invalidUserWorksheet.Range["A" + newWorkbookIndex + ":M" + newWorkbookIndex];

对于复制行:

对于删除行: