【问题标题】:How to Update filename based highest value of files names from other two columns如何从其他两列更新基于文件名的最高文件名值
【发布时间】:2014-09-22 23:07:37
【问题描述】:

我需要根据其他两列中文件名的最高名称来更新文件名。 例如:- 我有名为 221-8812_01 的 coumn3 和名为 221-8812_02 的 column4。所以我想将221-8812_02 文件名更新为column1。

反之亦然,如果我在 column3 中有一个名为 323-1111_03 的文件名,在 column3 中有一个名为 323-1111_02 的文件,那么我想在 column1 中更新 323-1111_03。

注意:- 我有像 323-2332_0A 和 323-2332_0B 这样的文件名。所以我需要更新 column1 中的 323-2332_0B。 或者可能是 111-4334_0D 和 111-4334_0C 所以我需要将 111-4334_0D 更新到 column1。

所以它就像 第一个服务器编号保持不变。在七个数字之后..当(_)下划线开始时..我需要比较..根据字母或数字升序!!!! 我该怎么做呢,

我的代码sn-p:

 private void filter_table()
    {
 // create a check box in column0
        DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
        DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
        colCB.HeaderCell = cbHeader;
        dataGridView1.Columns.Add(colCB);


        //Initialize Directory path
        string draft = ini.ReadValue("Location", "Draft");
        string release = ini.ReadValue("Location", "Release");
        string drawing = ini.ReadValue("Location", "Drawing");
        string archive = ini.ReadValue("Location", "Archive");

        if (!System.IO.Directory.Exists(draft))
            System.IO.Directory.CreateDirectory(draft);
        if (!System.IO.Directory.Exists(release))
            System.IO.Directory.CreateDirectory(release);
        if (!System.IO.Directory.Exists(drawing))
            System.IO.Directory.CreateDirectory(drawing);
        if (!System.IO.Directory.Exists(archive))
            System.IO.Directory.CreateDirectory(archive);

        string[] arrDraft = Directory.GetFiles(draft, "*", SearchOption.AllDirectories);
        string[] arrRelease = Directory.GetFiles(release, "*", SearchOption.AllDirectories);
        string[] arrDrawing = Directory.GetFiles(drawing, "*", SearchOption.AllDirectories);
        string[] arrArchive = Directory.GetFiles(archive, "*", SearchOption.AllDirectories);

        dt.Columns.Add("Drawing_Number");
        //dt.Columns["Part Number"].ReadOnly = true;

        dt.Columns.Add("Drawing");
        // dt.Columns["Drawing"].ReadOnly = true;

        dt.Columns.Add("Draft Path");
        // dt.Columns["Draft Path"].ReadOnly = true;

        dt.Columns.Add("Release Path");
        //  dt.Columns["Release Path"].ReadOnly = true;

        dt.Columns.Add("Error");
        //  dt.Columns["Error"].ReadOnly = true;

        dt.Columns.Add("Archive");

   // listing all the files according to the column3(draft path) filename.. and mating files from nearby column.
        List<FileDetails> lst = new List<FileDetails>();
        foreach (string file in arrDraft)
        {
            Finder finder = new Finder(Path.GetFileNameWithoutExtension(file).Substring(0, 7));
            string abc = Array.Find(arrRelease, finder.Match);
            string cdf = Array.Find(arrDrawing, finder.Match);
            string ghi = Array.Find(arrArchive, finder.Match);
            dt.Rows.Add(Path.GetFileNameWithoutExtension(file), cdf, file, abc, String.Empty, ghi);
        }

        dataGridView1.DataSource = dt;
    }

  private void Form1_Load(object sender, EventArgs e)
    {
        filter_table();
   }

   // Search predicate returns true if a string ends in "saurus".
    private static bool MatchFileName(String s, String _match)
    {
        return ((s.Length > 5) && (s.Substring(0, 7).ToLower() == _match.ToLower()));
    }


    public class FileDetails
    {
        public string FileName;
        public string Drawings;
        public string FilePathDraft;
        public string FilePathRelease;
        public string Comment;
        public string ErrorMsg;
    }
    public sealed class Finder
    {
        private readonly string _match;

        public Finder(string match)
        {
            _match = match.ToLower();
        }

   //findin the match and showing in grid view
        public bool Match(string s)
        {
            string fileName = s.Substring(s.LastIndexOf("\\") + 1);
            return ((fileName.Length > 5) && (fileName.Substring(0, 8).ToLower() == _match));
        }
    }

【问题讨论】:

  • 为什么323-2332_0B“高于”323-2332_0A,但111-4334_0C高于111-4334_0D
  • @DourHighArch 我正在寻找 _0A、0B、0C .. 继续。到 0Z.. 而在数字上它就像 _01, 02, 03, 04, 05, 06, 07 .. 最后两个数字一样
  • @Shell.. 任何想法!!!
  • 您需要的是一种方法(或 IComparable 的实现),它可以比较 2 个字符串并返回“更高”的字符串。我们无法帮助您进行比较逻辑,因为正如上面@DourHighArch 指出的那样,您的比较逻辑没有多大意义。即 B > A 但 C > D。一旦你知道哪个字符串的结果更高,你就可以继续更新你需要的任何列。
  • @failedprogramming 我已经指定了更高的原因..我正在寻找最后两个值.._0A、0B、0C..继续。到 0Z.. 而在数字上它就像 _01, 02, 03, 04, 05, 06, 07 .. 寻找最后两个数字

标签: c# wpf filenames


【解决方案1】:

让我们变得简单

string A = "323-1111_0A";
string B = "323-1111_0D";
MessageBox.Show(TakeLarger(A, B));

private string TakeLarger(string first, string second)
{
    int iResult = first.Substring(first.LastIndexOf("_")+1).CompareTo(second.Substring(second.LastIndexOf("_")+1));

    return (iResult == -1) ? second : first;
}

输出:

323-1111_0D

如果最后两位是十六进制值,则可以使用此方法。

string A = "323-1111_FF";
string B = "323-1111_1D";
MessageBox.Show(TakeLarger(A, B));

private string TakeLargerHex(string first, string second)
{
    int iFirst = Convert.ToInt32(first.Substring(first.LastIndexOf("_")+1), 16);
    int iSecond = Convert.ToInt32(second.Substring(second.LastIndexOf("_")+1), 16);
    return (iFirst > iSecond) ? first : second;
}

输出:

323-1111_FF

如果文件名存储在您的网格单元格中,例如MY_FILE_323-1111_FF.doc,那么您需要从末尾删除扩展名,否则您可以直接使用。

string A = dataGridView.Rows[i].Cells[2].Value.ToString();
string B = dataGridView.Rows[i].Cells[3].Value.ToString();

如果扩展名包含在字符串的末尾,那么您可以像这样删除。

A = A.Substring(A.LastIndexOf(".")+1);

【讨论】:

  • 如何合并到我上面的代码中……它也应该是这样的……那个数字。它一直持续到 1000 .. 像 01、02、03、04、05、06、07、08、09、10、11、12、13、14,像这样.. 直到 1000。还有字母表。像0A,0B,0C,0D,0E,0F ..这样直到0Z ..如果0Z来了,它应该去.. 1A,1B,1C,1D,1E。直到 1Z.. 如果 1Z 数字和字母达到.. 那么文件编号可能会继续为.. 2A..2 B, 2C,, 像那样.. 你能这样吗
  • 你的意思是value可以像323-2332_1000或者323-2332_1Z
  • 如果值是 00 到 09 和 A0 到 FF 那么它的十六进制值不是字符串。在这种情况下,您需要使用第二种方法。如果值可以大于F,例如 1G、2L、9Z,那么它的字符串值。在这种情况下,您可以使用第一种方法。
  • 我们有很多文件名shell。将来我们的文件名最多从 00 到 100000。我们的旧文件名就像.. 从 0A 开始,它可能会上升到 9Z。
  • 那你应该试试第一种方法。
【解决方案2】:

根据您的逻辑,我提出了一种快速简单的方法来比较 2 个字符串并确定哪个更高。

请注意:

  • 您可能想要修改此代码并改为实现 IComparable
  • 如果您喜欢将代码用作如下静态方法,则需要处理两个字符串相等的情况
  • 如果您确信前 7 个数字始终相同,则可以省略该逻辑
  • 我的逻辑假设位置是固定的。如果位置是动态的,则需要修改代码以使用 string.IndexOf("_")

    搜索下划线
    // returns true if a is "higher" than b
    // example string format 323-2332_0A
    private static bool IsHigher(string a, string b)
    {
        if(string.CompareOrdinal(a.ToUpper(), b.ToUpper()) == 0)
            throw new InvalidOperationException("The strings are equal!");
    
        // Compare first 3 numbers
        var inta = Convert.ToInt32(a.Substring(0, 3));
        var intb = Convert.ToInt32(b.Substring(0, 3));
        var result = inta.CompareTo(intb);
    
        if (result > 0) return true; // a is "higher" than b
        if (result < 0) return false; // b is "higher" than a
        // if a = b, code continues down ...
    
        // Compare middle 4 numbers
        inta = Convert.ToInt32(a.Substring(4, 4));
        intb = Convert.ToInt32(b.Substring(4, 4));
        result = inta.CompareTo(intb);
    
        if (result > 0) return true; // a is "higher" than b
        if (result < 0) return false; // b is "higher" than a
        // if a = b, code continues down ...
    
        // Compare last number
        inta = Convert.ToInt32(a.Substring(9, 1));
        intb = Convert.ToInt32(b.Substring(9, 1));
        result = inta.CompareTo(intb);
    
        if (result > 0) return true; // a is "higher" than b
        if (result < 0) return false; // b is "higher" than a
        // if a = b, code continues down ...
    
        // Compare alphabet
        var stringa = a.Substring(10, 1).ToUpper();
        var stringb = b.Substring(10, 1).ToUpper();
        result = String.CompareOrdinal(stringa, stringb);
    
        if (result > 0) return true; // a is "higher" than b
        if (result < 0) return false; // b is "higher" than a
    
        return true; // we should not get here.
    
    }
    

编辑

您可能会在将行添加到数据网格之前使用此代码。

例如,如果您想将字符串与当前文件名进行比较,并且只选择“较高”的那个,您可以这样做。

Finder finder = new Finder(Path.GetFileNameWithoutExtension(file).Substring(0, 7));
string abc = Array.Find(arrRelease, finder.Match);
string cdf = Array.Find(arrDrawing, finder.Match);
string ghi = Array.Find(arrArchive, finder.Match);
var filenameonly = Path.GetFileNameWithoutExtension(file);
dt.Rows.Add(filenameonly, 
            IsHigher(filenameonly, cdf) ? filenameonly : cdf, 
            file, 
            IsHigher(filenameonly, abc) ? filenameonly : abc, 
            String.Empty, 
            IsHigher(filenameonly, ghi) ? filenameonly : ghi
           );

【讨论】:

  • 实际上你可以编辑..这个程序以这样的方式..数字。它一直持续到 1000 .. 像 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 像这样.. 直到 1000。还有字母表。像0A,0B,0C,0D,0E,0F ..这样直到0Z ..如果0Z来了,它应该去.. 1A,1B,1C,1D,1E。直到 1Z.. 如果 1Z 数字和字母达到.. 那么文件编号可能会继续为.. 2A..2 B, 2C,, 像这样..
  • @StacyKebler 我相信我给你的东西足以让你走上正轨。正如我在回答中提到的,如果您的字符位置是动态的,则需要使用 string.IndexOf() 来查找下划线/连字符的位置。一旦你有了它,你就可以使用 string.Substring() 方法来切片所需的部分。
  • @StacyKebler 请查看我的编辑。我已经解释了如何使用此代码。
  • 让我检查并告诉你
猜你喜欢
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
  • 2019-08-20
  • 2020-11-17
相关资源
最近更新 更多