Как сохранить последнюю запись и удалить старую, используя C # Interop - PullRequest
0 голосов
/ 05 декабря 2011

У меня есть файл 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

, в этом примере дата указывается в ММ / ДД / ГГГГ.

Будут оценены любые предложения

Ответы [ 2 ]

1 голос
/ 06 декабря 2011

Полагаю, вам нужно сгруппировать по имени, взять последнюю дату для каждой группировки, а затем выбрать только ID из результата.SELECT Table1.ID, MAX(Table1.Date) FROM Table1 GROUP BY Table1.Name.Поэтому после получения этого запроса просто используйте поле ID.

Затем выполните запрос на удаление (код Psuedo) 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.

0 голосов
/ 06 декабря 2011

Если вы не уверены, что хотите использовать это как внешнюю программу, использующую c # с COM Interop to Excel, вы можете найти здесь полезную информацию о макросах:

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

В противном случаевам нужно будет создать новый проект C # в Visual Studio и добавить ссылки на 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();
        }
    }
}
...