如何使用C#Interop保留最新记录并删除旧记录

时间:2011-12-05 19:52:15

标签: c# interop xls

我有一个包含四列的xls文件

ID          Name           Date       File
1           charlie        01/09/2011 1.txt
2           charlie        12/25/2005 2.txt
3           nero           11/11/2011 3.txt
4           charlie        12/09/2011 4.txt

该过程将能够删除查理的旧记录并保留最新记录 基于名称和日期,其他列将被忽略。

预期xls将有以下记录

ID          Name           Date       File
3           nero           11/11/2011 3.txt
4           charlie        12/09/2011 4.txt

在此示例中为MM / DD / YYYY中的日期。

任何建议都将受到赞赏

2 个答案:

答案 0 :(得分:1)

我认为您需要按名称分组,并为每个分组记录最近的日期,然后从结果中仅选择IDSELECT Table1.ID, MAX(Table1.Date) FROM Table1 GROUP BY Table1.Name。因此,在您获得此查询后,只需使用ID字段。

接下来执行删除查询(Psuedo Code)DELETE FROM [Table] WHERE [Table].ID NOT IN (result from above)

使用LINQ to SQL完成以下操作:

static void Main(string[] args)
    {
        using(var db = new DataClasses1DataContext())
        {
            var query = db.Table1s.GroupBy(x => x.Name)
                .Select(x => new
                                 {
                                     ID = x.Max(t => t.ID),
                                     Name = x.Max(t => t.Name),
                                     Date = x.Max(t => t.Date)

                                 });

            foreach (var n in query)
            {
                Console.WriteLine(n.ID + " " + n.Name + " " + n.Date);
            }
            Console.WriteLine("");
            //Result:
            //4 charlie 12/9/2011
            //3 nero 11/11/2011

            var deleteQuery = db.Table1s.Where(x => !query.Select(t=> t.ID)
                                        .Contains(x.ID));

            db.Table1s.DeleteAllOnSubmit(deleteQuery);
            db.SubmitChanges();

            var testDeletion = db.Table1s;

            foreach (var n in testDeletion)
            {
                Console.WriteLine(n.ID + " " + n.Name + " " + n.Date);   
            }
        }
    }

此代码是针对数据库完成的,但基本逻辑仍适用于excel文件。

答案 1 :(得分:0)

如果您不确定是否希望将此作为外部程序使用带有COM Interop to Excel的c#,您可以在此处找到有关宏的一些有用信息:

http://office.microsoft.com/en-gb/excel-help/create-or-delete-a-macro-HP010014111.aspx

否则,您需要在visual studio中创建一个新的C#项目,并添加对Microsoft.Office.Core和Microsoft.Office.Interop.Excel的引用。

完成后,您可以执行以下操作(注意:您需要更好的错误清理):

using System;
using System.Collections.Generic;
using System.IO;

using Microsoft.Office.Interop.Excel;

namespace ExcelInterop
{
    class Program
    {
        static void Main(string[] args)
        {
            Application app = new Application();
            try
            {
                FileInfo fiSource = new FileInfo(args[0]);
                FileInfo fiDest = new FileInfo(args[1]);
                Workbook wb = app.Workbooks.Open(fiSource.FullName,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                    Type.Missing, Type.Missing);
                Worksheet sheet = (Worksheet)wb.Sheets[1];

                Dictionary<string, DateTime> hashNewest = new Dictionary<string, DateTime>();
                for (int iRow = 1; iRow < (double)sheet.Cells.Height; ++iRow )
                {
                    object oID = sheet.get_Range("A" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    if (oID == null || oID.ToString().Trim().Length <= 0)
                        break;

                    object oName = sheet.get_Range("B" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    string strName = "" + oName;
                    object oDate = sheet.get_Range("C" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    DateTime dt = Convert.ToDateTime(oDate);
                    if( !hashNewest.ContainsKey(strName) )
                        hashNewest.Add(strName, dt);
                    else if (hashNewest[strName].CompareTo(dt) < 0)
                        hashNewest[strName] = dt;
                }

                for (int iRow = 1; iRow < (double)sheet.Cells.Height; ++iRow)
                {
                    object oID = sheet.get_Range("A" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    if (oID == null || oID.ToString().Trim().Length <= 0)
                        break;

                    object oName = sheet.get_Range("B" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    string strName = "" + oName;
                    object oDate = sheet.get_Range("C" + (iRow + 1), Type.Missing).get_Value(Type.Missing);
                    DateTime dt = Convert.ToDateTime(oDate);
                    if (!hashNewest[strName].Equals(dt))
                    {
                        sheet.get_Range(
                            string.Format("A{0}:D{0}", iRow+1),
                            Type.Missing
                            ).Delete(XlDeleteShiftDirection.xlShiftUp);
                        --iRow;
                    }
                }

                File.Delete(fiDest.FullName);
                wb.SaveAs(fiDest.FullName, Type.Missing, Type.Missing, Type.Missing, 
                    Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, 
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing );

                wb.Close(false, Type.Missing, Type.Missing);
            }
            finally
            {
                app.Workbooks.Close();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
            }
            Console.WriteLine("Hit any key to continue");
            Console.ReadKey();
        }
    }
}