现在的位置: 首页 > 综合 > 正文

关于Excel操作编写的一个软件设计构思案例[连载] –辅助功能:补全缺少数据、树定位、文本读与保存

2013年02月11日 ⁄ 综合 ⁄ 共 4986字 ⁄ 字号 评论关闭

由于原字符有些写的资料有的是标准十级文字,有的不足十级文字,有的又有多余,户名有的没写,故此,设计补缺2个功能,还有一个标准地址自动校正功能,看代码:

        private void 补缺地址(string 标准地址)
        {
            int 选行 = 处理结果.CurrentCellAddress.Y, 行量 = 处理结果.RowCount - 1;/*, 选列 = 处理结果.CurrentCellAddress.X*/
            List<string> 字符 = new List<string>(), 数据 = new List<string>(); string 合成 = ""; int 数 = 8;
            if (处理结果.RowCount > 0)
            {
                if (标准地址 == "") for (int 列 = 1; 列 < 8; 列++) 字符.Add(处理结果.Rows[选行].Cells[列].Value.ToString());
                else { 字符.AddRange(标准地址.Split('☆')); 数 = 字符.Count + 1; }
                for (int 行 = 0; 行 < 行量; 行++)
                {
                    数据 = new List<string>();
                    for (int 列 = 1; 列 < 数; 列++) 数据.Add(处理结果.Rows[行].Cells[列].Value.ToString());
                    if (数据[0] == 字符[0] && 数据[1] == 字符[1])
                    {
                        if (数据[4] == 字符[4])
                            for (int 列 = 2; 列 < 4; 列++) 处理结果.Rows[行].Cells[列 + 1].Value = 字符[列];
                        if (数据[6] == 字符[6] && 数据[6] != "/")
                            for (int 列 = 2; 列 < 5; 列++) 处理结果.Rows[行].Cells[列 + 1].Value = 字符[列];
                    }
                }
                foreach (string 内容 in 字符) if (合成 == "") 合成 = 内容; else 合成 += "☆" + 内容;
                读文本("标准地址", 合成);
            }
        }

        private void 补缺户名()
        {
            int 选行 = 处理结果.CurrentCellAddress.Y, 行量 = 处理结果.RowCount - 1;/*, 选列 = 处理结果.CurrentCellAddress.X*/
            string 户名 = "", 原地址内容 = "", 原空缺 = "";
            if (MessageBox.Show("您确认未对导入信息进行任何修改情况下执行[户名补缺]吗?是您确认信息可靠情况下执行?如果您确定要执行,请按[确定]按钮。", "确认执行?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                for (int 行 = 0; 行 < 行量; 行++)
                {
                    处理结果.Invoke(new Action(delegate() { 处理结果.CurrentCell = 处理结果.Rows[行].Cells[11]; }));
                    户名 = 处理结果.Rows[行].Cells[10].Value.ToString(); 原地址内容 = 处理结果.Rows[行].Cells[11].Value.ToString();
                    if (户名 != "")
                        for (int 补行 = 0; 补行 < 行量; 补行++)
                        {
                            原空缺 = 处理结果.Rows[补行].Cells[10].Value.ToString();
                            if (原空缺 == "") if (原地址内容 == 处理结果.Rows[补行].Cells[11].Value.ToString()) { 处理结果.Rows[补行].Cells[10].Value = 户名; break; }
                        }
                }
                地址树(); 地址分类树.ExpandAll(); if (树定位.Text != "") 地址分类树.SelectedNode = 树定位;
        }

如上补缺地址代码中将提取已编辑好的标准地址写入地址标准文本保存,作为标准地址功能调用,看代码:

        private void 记录文本(string 输出内容, string 文件名称)
        {
            String 保存路径 = @System.Environment.CurrentDirectory , 保存文件名 = @保存路径 + "\\" + 文件名称 + ".txt";
            if (Directory.Exists(保存路径))
            {
                FileInfo 文件 = new FileInfo(保存文件名);
                if (!文件.Exists) { FileStream 创建或覆盖 = File.Create(保存文件名); 创建或覆盖.Flush(); 创建或覆盖.Close(); }
                StreamWriter 写入 = new StreamWriter(保存文件名, true);//以可以追加文本的方式打开文件流
                写入.WriteLine(输出内容); 写入.Flush(); 写入.Close();
            }
            else
            {
                Directory.CreateDirectory(保存路径);
                FileStream 创建或覆盖 = File.Create(保存文件名);
                创建或覆盖.Flush(); 创建或覆盖.Close();
                StreamWriter 写入 = new StreamWriter(保存文件名);//不可追加文本
                写入.WriteLine(输出内容); 写入.Flush(); 写入.Close();
            }
        }

        private void 读文本(string 文件名称, string 比较内容)
        {
            String 保存路径 = @System.Environment.CurrentDirectory , 文件名 = @保存路径 + "\\" + 文件名称 + ".txt";
            List<string> 内容 = new List<string>(); bool 控制 = true;
            if (Directory.Exists(保存路径))
            {
                FileInfo 文件 = new FileInfo(文件名);
                if (!文件.Exists)
                {
                    记录文本("标准地址保存文件,请勿删除,以免影响程序正常运行。", 文件名称);
                    记录文本(比较内容, 文件名称); MessageBox.Show(文件名称 + ":已创建并完成写入数据。", "友情提示!");
                }
                if (文件.Exists)
                {
                    using (FileStream 打开 = new FileStream(文件名, FileMode.Open))
                    {
                        using (StreamReader 读取 = new StreamReader(打开, Encoding.UTF8))
                        {
                            while (!读取.EndOfStream)
                            {
                                if (比较内容 == "") 内容.Add(读取.ReadLine());
                                else
                                    if (比较内容 == 读取.ReadLine()) { 控制 = false; break; }
                            }
                            打开.Close(); if (控制) 记录文本(比较内容, 文件名称);
                        }
                    }
                }
            }
            foreach (string 数据 in 内容) if (数据.Contains("☆")) { 补缺地址(数据); }
        }

软件实际操作中,有时需把提取的文字在不同级间作调整,而各级存储的文字数量有多有少,用鼠标滚蛋去各列各行找很麻烦的,为此,设计查找功能,看代码:

        private void 查找字符()
        {
            int 行 = 处理结果.CurrentCellAddress.Y, 列 = 处理结果.CurrentCellAddress.X;
            string 字符 = 处理结果.Rows[行].Cells[列].Value.ToString();
            for (int 字符行 = 0, 量 = 条件设定.RowCount - 1; 字符行 < 量; 字符行++)
            {
                if (列 < 条件设定.ColumnCount - 1)
                    if (字符.Contains(条件设定.Rows[字符行].Cells[列 - 1].Value.ToString()))
                    { 条件设定.CurrentCell = 条件设定.Rows[字符行].Cells[列 - 1]; break; }
            }
        }

最后看有关树的一些代码,以及对树的定位,看代码:

        private void 地址树()
        {
            this.Invoke(new Action(delegate()
            {
                DataTable 树表 = new DataTable();
                for (int 空 = 0; 空 != 10; 空++) 树表.Columns.Add(空.ToString());
                for (int 行 = 0, 数 = 处理结果.RowCount; 行 < 数; 行++)
                {
                    树表.Rows.Add();
                    for (int 列 = 1, 量 = 处理结果.ColumnCount - 1; 列 < 量; 列++)
                    { 
                        string 数据 = 处理结果.Rows[行].Cells[列].Value.ToString();
                        if (列 != 6)
                            if (数据 != "" && 数据 != "/") 树表.Rows[行][列 - 1] = 数据;
                            else 树表.Rows[行][列 - 1] = "?";
                        else 树表.Rows[行][列 - 1] = "/";
                    }
                }
                玄龙戏珠无级树(树表);
            }));
        }

        private void 玄龙戏珠无级树(DataTable 数据表)
        {
            this.Invoke(new Action(() =>
            {
                地址分类树.Nodes.Clear();
                List<TreeNode> 子节 = new List<TreeNode>(); 子节.Add(new TreeNode()); int 列数 = 数据表.Columns.Count, 行数 = 0; List<TreeNode>[] 节存 = new List<TreeNode>[列数 - 1];
                for (int 级 = 0; 级 != 列数 - 1; 级++) { 节存[级] = new List<TreeNode>(); 子节.Add(new TreeNode()); }
                /*玄龙戏珠无级树=>开始*/
                foreach (DataRow 数据列 in 数据表.Rows)
                {
                    bool 节控 = false;
                    for (int 级 = 0; 级 != 列数; 级++)
                    {
                        string 节路径 = "";
                        if (地址分类树.Nodes.Count == 0) 节控 = true;
                        for (int 数 = 0; 数 <= 级; 数++) { if (节路径 == "") 节路径 = 数据列[数].ToString(); else 节路径 += "\\" + 数据列[数].ToString(); }
                        if (级 < 列数 - 1) foreach (TreeNode 节数据 in 节存[级]) { if (节路径 == 节数据.FullPath) { 子节[级] = 节数据; 节控 = false; break; } else 节控 = true; } else 节控 = true;
                        if (节控 && 级 == 0)
                        {
                            TreeNode 节点 = new TreeNode();
                            节点.Tag = 行数; 节点.Text = 数据列[0].ToString();
                            /*节点.ImageIndex = 3; 节点.SelectedImageIndex = 2;图标按条件自编*/
                            节存[级].Add(节点); 子节[级] = 节点;
                            地址分类树.Nodes.Add(节点);
                        }
                        if (级 > 0 && 节控)
                        {
                            TreeNode 加子节 = new TreeNode();
                            加子节.Tag = 行数; 加子节.Text = 数据列[级].ToString();
                            if (数据列[级].ToString() == 树定位.Text) 树定位 = 加子节;
                            /*加子节.ImageIndex = 4; 加子节.SelectedImageIndex = 5;图标按条件自编*/
                            if (级 < 列数 - 1) 节存[级].Add(加子节); 子节[级] = 加子节; 子节[级 - 1].Nodes.Add(加子节);
                        }
                        if (级 < 列数 - 1) 节存[级] = 节存[级].Distinct().ToList();
                    }
                    行数++;
                }
            }));
        }

        private void 地址分类树_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if ((object)e.Node.Tag != null)
            {
                int 行数 = (int)e.Node.Tag;
                if (处理结果.RowCount > 0) 处理结果.CurrentCell = 处理结果.Rows[行数].Cells[11];
                树定位 = e.Node;
            }
        }

至此本连载全部介绍和代码都发布完整;由于急用只考虑功能实现,马上投入使用,这些代码未经任何调整和优化,当发布时发现有很多地方可调整和优化的,仅作案例参考也就直接发布了。

抱歉!评论已关闭.