精华内容
下载资源
问答
  • 案例:下图B列日期中,橘黄色部分是我们已经标记好颜色的重复项。要求:快速删除橘黄色的重复日期;另外请思考,如何快速找出重复项?原始数据方法1:普通筛选法step1:选中B列「日期」列数据→点击「排序和筛选」;...

    快速删去重复数据,雷哥在这里提供4种超简单的解决方法,大家一看就会。

    为了更加直接明了地说明,雷哥在这里通过具体案例进行讲解。

    案例:下图B列日期中,橘黄色部分是我们已经标记好颜色的重复项。

    要求:快速删除橘黄色的重复日期;另外请思考,如何快速找出重复项?

    4e3e0a1fb2a0659b4c5b7788fcabaf7a.png

    原始数据

    方法1:普通筛选法

    step1:选中B列「日期」列数据→点击「排序和筛选」;

    step2:单击「筛选」按钮→点击筛选下拉三角,按颜色筛选→单击标记的橘黄色重复项→全选中橘红色部分,全部删除;

    step3:再次点击筛选下拉三角,点击「全选」,以此恢复剩余的非重复日期,搞定。

    具体步骤见动图,是不是感觉删去重复日期原来是如此简单呢?

    45d06068ff635b95df840a000a96a457.gif

    方法2:高级筛选法

    学习了普通的筛选法,雷哥再跟大家分享下高级筛选的方法。

    step1:单击「数据」选项卡中的「高级」筛选功能,列表区域选择「B1:B15」;

    step2:选择「将筛选结果复制到其他区域」,复制到选择E1单元格,勾选「选择不重复区域」,单击「确定」。

    具体操作流程见下图。

    e917cfe6b7528685c18fd93d87b579e6.gif

    方法3:查找法去重法

    step1:选中「日期」列数据,按下快捷键「Ctrl+F」组合键弹出查找对话框 (或者单击“查找和选择”-查找工具);

    step2:点击「选项」按钮,单击查找内容右侧对应的「格式」下拉三角→在「填充」选项处单击“从单元格选择格式”→单击某一个橘黄色的重复项→确认后单击“查找全部”;

    3654c462a2ace3048dc62b821fb10554.gif

    step3:单击查找的第一个项目后,按「Ctrl+A」组合键全选(或者按住第一个项目后,按住shift键,按住最后查找到的项目)查找的橘黄色项目,然后全部删除即可。

    1d9731ac60feec731e4b4f64078092f8.gif

    方法4:合并计算去重法

    step1:在「辅助列」数据C2单元格中输入数据11后,单击D1单元格;

    step2:单击「数据」选项卡 → 「合并计算」 → 引用位置选择「B1:C15」,勾选最左行,单击确定。

    可以发下,E列的数据就是B列日期去重后的数据。是不是感觉很神奇呢?

    9b43486437a955c8b2c1645cbc896809.gif

    知识拓展:我们如何快速找到重复项?

    方法1: 条件格式法

    选中数据,单击「条件格式」→「突出显示单元格规则」→「重复值」。

    可以快速突出显示重复的数值。

    0d06dc033953fcd64955b758761ad827.gif

    方法2:Countif函数法

    为了让大家知识更加丰富,雷哥分享一个不是特别快速的方法,但是知识点需要大家掌握。

    分析:D2单元格中,输入公式=COUNTIF(B:B,B2),并下拉该公式,可以快速统计出公式所在行的日期在所有区域中累计出现的次数。

    那么问题来了,经过筛选发现,有些项目是重复项,但是第一次出现的该日期也被筛选出来了,如下图,显然不是我们想要的结果,比如“2014/1/2”这个重复项,即使首次出现,也被筛选出来了,这种方法是能判定出哪一项是重复项。

    1e6c14bcb6a277fb63bb1cf298d5c306.png

    优化的解决方法

    使用公式=COUNTIF($B$2:B2,B2),并下拉该公式,可以快速统计出从第一个日期到公式所在行的日期数据区域范围内出现的次数。

    注意此处$B$2是绝对引用(选中原来的B2,用F4键切换成$B$2)。

    筛选后发现,此时问题得以有效解决,如下图所示。

    5e11df4f38af2c2184fabee9404d0fe5.png

    Countif函数语法

    Countif函数是对指定区域中符合指定条件的单元格计数的函数,语法是countif(range,criteria),参数1 range是要计算其中非空单元格数目的区域,参数2 criteria是以数字、表达式或文本形式定义的条件。

    总结

    本文中,雷哥通过案例,讲解了4种方法,实现Excel中重复项数据的删去,分别是

    ①筛选法

    ②高级筛选法

    ③查找去重法

    ④合并计算去重法

    各位朋友,你们都学会了吗?

    展开全文
  • 假设我们枚举到的是两个红色点,那么路径上的合法中转点(蓝色点)就是图中标记的部分 显然,这两点路径上的点双中的每个点都是可以取到的 我们可以把所有方点的权值赋为它所管辖的点双大小 这样,以两个红点为...

    题面

     

     

    题解

    比较容易想到建广义圆方树

    关键是怎样给点赋权

    如果我们枚举了路径的两个端点

    那么有多少个中转点是合法的呢?

    假设我们枚举到的是两个红色点,那么路径上的合法中转点(蓝色点)就是图中标记的部分

    显然,这两点路径上的点双中的每个点都是可以取到的

    我们可以把所有方点的权值赋为它所管辖的点双大小

    这样,以两个红点为路径端点的合法中转点个数就是其路径的点权和

    但是由于路径两端的端点是不能取到的,并且两个方点之间的公共圆点会被重复算

    所以还应该将所有圆点的点权赋为-1

     

    还有一个问题,我们不能直接枚举所有的点对来计算贡献

    我们先把答案的式子列出来

    \sum_{P}\sum_{i\in P} val_i(P是枚举的路径)

    交换求和号

    \sum_ival_i\sum_{i\in P}1

    就变成了对经过i点的路径条数的计数问题

    简单DP即可

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    inline int gi()
    {
    	char c;int num=0,flg=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
    	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
    	return num*flg;
    }
    #define N 200005
    int n,m;
    vector<int> G[N],gid[N];
    int fir[N],to[2*N],nxt[2*N],cnt;
    void adde(int a,int b)
    {
    	to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
    }
    int tot;
    int dfn[N],low[N],stk[N],top,pbccnt,dc;
    int pbcsiz[N],all;
    void dfs(int u,int pp)
    {
    	if(u<=n)all++,pbcsiz[u]=-1;
    	dfn[u]=low[u]=++dc;
    	stk[top++]=u;
    	for(int v,i=0;i<int(G[u].size());i++){
    		if(gid[u][i]!=pp){
    			v=G[u][i];
    			if(!dfn[v]){
    				dfs(v,gid[u][i]);
    				low[u]=min(low[u],low[v]);
    				if(low[v]>=dfn[u]){
    					adde(u,++tot);pbcsiz[tot]=1;
    					while(top>0){
    						adde(tot,stk[--top]);
    						pbcsiz[tot]++;
    						if(stk[top]==v)break;
    					}
    				}
    			}
    			else low[u]=min(low[u],dfn[v]);
    		}
    	}
    }
    #define LL long long
    LL f[N],ans;
    void DP(int u,int ff)
    {
    	if(u<=n)f[u]=1;
    	for(int v,p=fir[u];p;p=nxt[p]){
    		if((v=to[p])!=ff){
    			DP(v,u);
    			ans+=1ll*f[u]*f[v]*pbcsiz[u];
    			f[u]+=f[v];
    		}
    	}
    	ans+=1ll*f[u]*(all-f[u])*pbcsiz[u];
    }
    int main()
    {
    	int i,u,v;
    	n=gi();m=gi();
    	for(i=1;i<=m;i++){
    		u=gi();v=gi();
    		G[u].push_back(v);gid[u].push_back(i);
    		G[v].push_back(u);gid[v].push_back(i);
    	}
    	tot=n;
    	for(i=1;i<=n;i++)
    		if(!dfn[i]){
    			all=0;dfs(i,0);
    			DP(i,0);
    		}
    	printf("%lld\n",2ll*ans);
    }

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 设备工程师最常见的一项工作就是备件清单梳理,每次当供应商提供一份元器件清单给我我们后,我们会先进行初步筛选...或者你把初版备件清单复制到库房台账的Excel里,标记重复项? 当然,这是其中的两种方法,可是你有没
      备件筛选工具,软件试用链接:https://download.csdn.net/download/weixin_44834086/12404203
    

    备件筛选工具试用链接:https://download.csdn.net/download/weixin_44834086/12404203
    软件演示视频链接:https://www.bilibili.com/video/BV145411s7fu/
    设备工程师最常见的一项工作就是备件清单梳理,每次当供应商提供一份元器件清单给我我们后,我们会先进行初步筛选,选出哪些是我们需要的,形成初步的备件清单,但这个清单不能直接提交给采购部,因为这个清单里可能存在库房里已经有的备件,这部分已经有的备件是不需要买的,我们必须把它们筛选出来删掉,才能提交给采购部购买。

    怎样才能知道哪些备件是库房里已经有的呢?
    你是不是会一个个的在库房台账Excel里按Ctrl+F查找?
    或者你把初版备件清单复制到库房台账的Excel里,标记重复项?
    当然,这是其中的两种方法,可是你有没有想过,这两种方法是不是就一定能达到我们的目的?
    你想想下面这种情况:一个备件供应商提供的型号是“QSL-1/4-10”,但库房台账里的型号却是“QSL 1/4-10”,型号里只是多一个“-”,此时用上述的两种方法搜索是没有匹配的结果的,但实际上这两个型号是一样的,这时你会认为库房买有,结果买回来后发现库房有相同的备件,造成浪费。(别说了,说多了都是泪,库房里还有好多型号不同但东西是一样的的备件)。

    这个事情没人管吗???!!!

    于是我就开发这个备件筛选工具,就是为了解决上面这个问题,该工具可以设置搜索的相似精度,备件型号里的特殊字符都会过滤掉,把可能相同的备件全部筛选出来,给设备工程师判断这些备件是否一样提供一个参考,避免备件的重复购买。

    如有bug欢迎提出,谢谢。
    软件界面如下所示:在这里插入图片描述
    如下图所示,设置搜索的相似精度为85%,软件完成搜索后会将搜索结果显示在窗体下方的DateGridView中,文件1中的哪一行,与文件2中的哪一行有相似的备件,设备工程师可以两个型号进行对比确认备件是否相同。
    在这里插入图片描述
    程序主要有以下功能:
    1、字符串处理(过滤字符串中的特殊字符);
    2、引用了两种字符串相似度的算法,并取两种算法算出的较大结果作为筛选的结果(可以避免漏选);
    3、生成结果清单(使用NPOI创建Excel文件,并将DateGridView中的数据写入Excel文件);
    4、生成备件清单(复制一份文件1,再使用NPOI将筛选出来的行删掉)

    主要代码如下:

    using System;
    using System.Linq;
    using System.Windows.Forms;
    using F23.StringSimilarity;
    using NP = NPOI.XSSF.UserModel;
    using System.IO;
    using System.Threading;
    using NPOI.HSSF.UserModel;
    using System.Drawing;
    using Excel = Microsoft.Office.Interop.Excel;
    using System.Reflection;
    using NPOI.SS.UserModel;
    using NPOI.XSSF.UserModel;
    using System.Collections;
    
    namespace 备件筛选工具
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Control.CheckForIllegalCrossThreadCalls = false;//程序加载时取消跨线程操作的访问                                            
                X = this.Width;//获取窗体的宽度
                Y = this.Height;//获取窗体的高度
                setTag(this);//调用方法
            }
    
    
            NPOI.SS.UserModel.ISheet sht1;//声明一个sheet  sht1
            NPOI.SS.UserModel.ISheet sht2;//声明一个sheet  sht2
            string FilePath1 = "";//声明字符串变量 文件1路径
            string FilePath2 = "";//声明字符串变量 文件2路径
            string fileName1 = "";
            string fileName2 = "";
            ArrayList matchRow = new ArrayList();
    
    
    
    
            //选择文件1
            private void Btn_Select1_Click(object sender, EventArgs e)
            {
                OpenFileDialog ofd1 = new OpenFileDialog();
                ofd1.InitialDirectory = @"C:\Users\28463\Desktop";//定义打开文件对话框的初始目录
                ofd1.Title = "请选择要筛选的文件";//定义打开文件对话框的名称
                ofd1.Filter = "所有文件|*.xls;*.xlsx";//过滤只显示Excel文件
                ofd1.ShowDialog(); //弹出打开文件对话框
                fileName1 = System.IO.Path.GetFileName(ofd1.FileName);//将文件1的名称赋值给文本框fileName
                text_FilePath1.Text = fileName1;//将文件1的名称赋值给文本框text_FilePath1.Text
                FilePath1 = ofd1.FileName;//将文件1的路径赋值给FilePath1
            }
    
    
            //选择文件2
            private void Btn_Select2_Click(object sender, EventArgs e)
            {
                OpenFileDialog ofd2 = new OpenFileDialog();
                ofd2.InitialDirectory = @"C:\Users\28463\Desktop";//定义打开文件对话框的初始目录
                ofd2.Title = "请选择要筛选的文件";//定义打开文件对话框的名称
                ofd2.Filter = "所有文件|*.xls;*.xlsx";//过滤只显示Excel文件
                ofd2.ShowDialog();//弹出打开文件对话框
                fileName2 = System.IO.Path.GetFileName(ofd2.FileName);//将文件2的名称赋值给文本框fileName
                text_FilePath2.Text = fileName2;//将文件2的名称赋值给文本框text_FilePath2.Text            
                FilePath2 = ofd2.FileName;//将文件2的路径赋值给FilePath1           
            }
    
            private void OpenFile1_Click(object sender, EventArgs e)
            {
                try
                {
                    System.Diagnostics.Process.Start(FilePath1);
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString() + "\r\n" + "请检查是否选择文件!", "错误提示"); //抛出异常信息
                }
            }
            private void OpenFile2_Click(object sender, EventArgs e)
            {
                try
                {
                    System.Diagnostics.Process.Start(FilePath2);
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString() + "\r\n" + "请检查是否选择文件!", "错误提示"); //抛出异常信息
                }
            }
    
            #region 过滤掉字符串中的特殊字符
            /// <summary>
            /// 过滤掉字符串中的特殊字符
            /// </summary>
            /// <param name="str">需要过滤字符串</param>
            /// <returns>过滤之后的字符串</returns>
            public static string ReplaceSymbol(string str)
            {
                if (str == String.Empty)
                    return String.Empty;
                //半角符号
                str = str.Replace("'", "");
                str = str.Replace("·", "");
                str = str.Replace(".", "");
                str = str.Replace(",", "");
                str = str.Replace(";", "");
                str = str.Replace(",", "");
                str = str.Replace("?", "");
                str = str.Replace("-", "");
                str = str.Replace("_", "");
                str = str.Replace("/", "");
                str = str.Replace("(", "(");
                str = str.Replace(")", ")");
                str = str.Replace("\\", "");
                //全角符号
                str = str.Replace(";", "");
                str = str.Replace(",", "");
                str = str.Replace("?", "");
                str = str.Replace("——", "");
                str = str.Replace("、", "");
                str = str.Replace("(", "");
                str = str.Replace(")", "");
                str = str.Replace("。", "");
    
                return str;
            }
            #endregion
    
            #region 利用Levenshtein方法计算两个字符串的相似率
            /// <summary>
            /// 利用Levenshtein方法计算两个字符串的相似率
            /// </summary>
            /// <param name="str1">字符串1</param>
            /// <param name="str2">字符串2</param>
            /// <returns>相似率</returns>
            private double Similarity1(string str1, string str2)
            {
                str1 = ReplaceSymbol(str1).ToLower();//将字符串str1中的特殊符号去掉,并把字母变成小写
                str2 = ReplaceSymbol(str2).ToLower();//将字符串str2中的特殊符号去掉,并把字母变成小写
                double maxlen = str1.Length > str2.Length ? str1.Length : str2.Length;//取两个字符串长度中的较大的值,赋值给maxlen
                var le = new Levenshtein();//实例化一个名称为le的Levenshtein对象,用于求从一个字符串变换到另一个字符串所需要的最短距离(步骤)
                double SimilarityRate = (1 - le.Distance(str1, str2) / maxlen);//计算相似率,其中le.Distance(str1,str2)为两个字符串转换的最短路径(步骤)
                return SimilarityRate;//返回相似率
            }
    
    
            #endregion
    
            #region 计算字符串相似度
            /// <summary>
            /// 获取两个字符串的相似度
            /// </summary>
            /// <param name=”str1”>第一个字符串</param>
            /// <param name=”str2”>第二个字符串</param>
            /// <returns></returns>
            private double Similarity2(string str1, string str2)
            {
                str1 = ReplaceSymbol(str1).ToLower();
                str2 = ReplaceSymbol(str2).ToLower();
                double Kq = 2;
                double Kr = 1;
                double Ks = 1;
    
                char[] ss = str1.ToCharArray();
                char[] st = str2.ToCharArray();
    
                //获取交集数量
                int q = ss.Intersect(st).Count();
                int s = ss.Length - q;
                int r = st.Length - q;
    
                return Kq * q / (Kq * q + Kr * r + Ks * s);
            }
            #endregion
    
            private bool IsContain(string str1, string str2)
            {
    
                str1 = ReplaceSymbol(str1).ToLower();
                str2 = ReplaceSymbol(str2).ToLower();
                return str2.Contains(str1);
            }
    
            private void Btn_SearchSimilarity_Click(object sender, EventArgs e)
            {
                flag_SearchStop = false;
                btn_Stop.Focus();
                matchRow.Clear();//清空集合matchRow中的数据
                dataGridView1.Rows.Clear();//清除dataGridView1表格数据
                btn_SearchContain.Enabled = false;
                SearchSimilarity();//调用“搜索相似”方法
                btn_SearchContain.Enabled = true;
    
            }
    
            private void Btn_SearchContain_Click(object sender, EventArgs e)
            {
                flag_SearchStop = false;
                btn_Stop.Focus();
                matchRow.Clear();//清空集合matchRow中的数据
                dataGridView1.Rows.Clear();//清除dataGridView1表格数据
                btn_SearchSimilarity.Enabled = false;
                SearchContain();//调用“搜索包含”方法
                btn_SearchSimilarity.Enabled = true;
            }
    
            /// <summary>
            /// 根据不同格式的Excel获取sheet(因为xlsx格式的Excel和xls格式的Excel获取sheet的方式不一样)
            /// </summary>
            /// <param name="FilePath">文件路径</param>
            /// <param name="fileName">文件名</param>
            /// <returns></returns>
            private NPOI.SS.UserModel.ISheet GetSheet(string FilePath, string fileName, int sheetIndex)
            {
                FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//必须要选择flieShare方式为ReadWrite,这样就可以在文件被打开的时候读取文件信息。
                if ((fileName.Split('.')[fileName.Split('.').Length - 1]).ToLower() == "xlsx")//判断文件1的文件名最后一个.后的字符串是否为xlsx
                {
                    NP.XSSFWorkbook wk = new NP.XSSFWorkbook(fs);//实例化一个.xlsx格式的工作簿
                    NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(sheetIndex);//根据“选择sheet”下拉列表框,获取工作表
                    return sht;
                }
                else //((fileName1.Split('.')[fileName1.Split('.').Length - 1]).ToLower() == "xls")//判断文件1的文件名最后一个.后的字符串是否为xls
                {
                    HSSFWorkbook wk = new HSSFWorkbook(fs);//实例化一个.xls格式的工作簿
                    NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(sheetIndex);//根据“选择sheet”下拉列表框,获取工作表
                    return sht;
                }
            }
    
            bool flag_SearchStop = false;
    
            private void SearchSimilarity()
            {
                try
                {
                    sht1 = GetSheet(FilePath1, fileName1, comboBox_sheet1.SelectedIndex);
                    sht2 = GetSheet(FilePath2, fileName2, comboBox_sheet2.SelectedIndex);
                    int rowsCount1 = sht1.LastRowNum;//获取工作表sht1的有效行数
                    int rowsCount2 = sht2.LastRowNum;//获取工作表sht2的有效行数
                    int listNumber = Convert.ToInt32(comboBox_list1.SelectedIndex);//根据“选择列:”下拉列表框的选择索引号,获取列                
                    progressBar1.Visible = true;//显示进度条
                    progressBar1.Maximum = rowsCount1;//设置进度条的最大值为sht1的行数+1
                    lbl_ProgressbarValue.Visible = true;//显示进度条百分比
    
    
                    for (int i = Convert.ToInt32(comboBox_Row1.Text) - 1; i <= rowsCount1; i++)//i为sht1的行数索引
                    {
    
                        progressBar1.Value = i;//定义进度条的值为i
                        lbl_ProgressbarValue.Text = (i * 100 / progressBar1.Maximum).ToString() + "%";//将进度条百分比赋值给文本框
                        Application.DoEvents();//重点,必须加上,否则窗体会假死
                        if (progressBar1.Value == progressBar1.Maximum)
                        {
    
                            MessageBox.Show("搜索完成,搜到" + (dataGridView1.Rows.Count - 1).ToString() + "个结果!", "搜索结果提示");
                            progressBar1.Value = 0;//将进度条数据置零
                            progressBar1.Visible = false;//隐藏进度条
                            lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比 
                            btn_SaveSearchResult.Enabled = true;//搜索完成后使能“保存搜索结果”按钮
                            btn_CreateResultExcel.Enabled = true;//搜索完成后使能“生成备件清单”按钮
                        }
                        if (!flag_SearchStop)
                        {
                            if (sht1.GetRow(i).GetCell(listNumber) != null)//如果sht1第i行第listNumber列不为空
                            {
                                string str1 = GetCellValue(sht1, i, listNumber);
                                if (str1 == "")
                                {
                                    continue;//如果读取的sht1第i行,第listNumber列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                }
    
                                else      //如果读取的sht1第i行,第listNumber列单元格的字符串的值不为空,则继续按下述循环判断sht2中的数据
                                {
                                    for (int j = Convert.ToInt32(comboBox_Row2.Text) - 1; j <= rowsCount2; j++)//j为sht2的行数索引
                                    {
                                        if (sht2.GetRow(j) != null)
                                        {
                                            if (comboBox_list2.Text == "搜索全部列")
                                            {
                                                for (int k = sht2.GetRow(j).FirstCellNum; k <= sht2.GetRow(j).LastCellNum; k++)//K为sht2的列数索引(或单元格索引)
                                                {
                                                    if (sht2.GetRow(j).GetCell(k) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                    {
                                                        string str2 = GetCellValue(sht2, j, k);
                                                        if (str2 == "")
                                                        {
                                                            continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                        }
                                                        else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                        {
                                                            double Simi = Similarity1(str1, str2) > Similarity2(str1, str2) ? Similarity1(str1, str2) : Similarity2(str1, str2);
                                                            if (Simi >= Convert.ToDouble(comboBox_accuracy.Text) / 100)
                                                            {
                                                                WriteToDateGridView(i, j, str1, str2);  //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                                ListAdd(i);//将匹配的行数存入集合中
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                    }
                                                }
                                            }
                                            else   //如果sheet2选择了列,则不搜索全部列,只搜索选择的列,可以大大减少搜索次数,提高搜索速度
                                            {
                                                if (sht2.GetRow(j).GetCell(comboBox_list2.SelectedIndex - 1) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                {
                                                    string str2 = GetCellValue(sht2, j, comboBox_list2.SelectedIndex - 1);
                                                    if (str2 == "")
                                                    {
                                                        continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                    }
                                                    else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                    {
                                                        double Simi = Similarity1(str1, str2) > Similarity2(str1, str2) ? Similarity1(str1, str2) : Similarity2(str1, str2);
                                                        if (Simi >= Convert.ToDouble(comboBox_accuracy.Text) / 100)
                                                        {
                                                            WriteToDateGridView(i, j, str1, str2); //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里
                                                            ListAdd(i);//将匹配的行数存入集合中
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                }
                                            }
    
                                        }
                                        else
                                        {
                                            continue;
                                        }
    
                                    }
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            break;
                        }
    
    
                    }
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString() + "\r\n" + "1.请检查是否选择文件!" + "\r\n" + "2.请检查文件的sheet和列是否选择正确!", "错误提示"); //抛出异常信息
                }
            }
    
            private void SearchContain()
            {
                try
                {
                    sht1 = GetSheet(FilePath1, fileName1, comboBox_sheet1.SelectedIndex);
                    sht2 = GetSheet(FilePath2, fileName2, comboBox_sheet2.SelectedIndex);
                    int rowsCount1 = sht1.LastRowNum;//获取工作表sht1的有效行数
                    int rowsCount2 = sht2.LastRowNum;//获取工作表sht2的有效行数
                    int listNumber = Convert.ToInt32(comboBox_list1.SelectedIndex);//根据“选择列:”下拉列表框的选择索引号,获取列                
                    progressBar1.Visible = true;//显示进度条
                    progressBar1.Maximum = rowsCount1;//设置进度条的最大值为sht1的行数+1
                    lbl_ProgressbarValue.Visible = true;//显示进度条百分比
    
    
                    for (int i = Convert.ToInt32(comboBox_Row1.Text) - 1; i <= rowsCount1; i++)//i为sht1的行数索引
                    {
                        progressBar1.Value = i;//定义进度条的值为i
                        lbl_ProgressbarValue.Text = (i * 100 / progressBar1.Maximum).ToString() + "%";//将进度条百分比赋值给文本框
                        Application.DoEvents();//重点,必须加上,否则窗体会假死
                        if (progressBar1.Value == progressBar1.Maximum)
                        {
                            MessageBox.Show("搜索完成,搜到" + (dataGridView1.Rows.Count - 1).ToString() + "个结果!", "搜索结果提示");
                            progressBar1.Value = 0;//将进度条数据置零
                            progressBar1.Visible = false;//隐藏进度条
                            lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比                        
                        }
                        if (!flag_SearchStop)
                        {
                            if (sht1.GetRow(i).GetCell(listNumber) != null)//如果sht1第i行第listNumber列不为空
                            {
                                string str1 = GetCellValue(sht1, i, listNumber);
                                if (str1 == "")
                                {
                                    continue;//如果读取的sht1第i行,第listNumber列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                }
    
                                else      //如果读取的sht1第i行,第listNumber列单元格的字符串的值不为空,则继续按下述循环判断sht2中的数据
                                {
                                    for (int j = Convert.ToInt32(comboBox_Row2.Text) - 1; j <= rowsCount2; j++)//j为sht2的行数索引
                                    {
                                        if (sht2.GetRow(j) != null)
                                        {
                                            if (comboBox_list2.Text == "搜索全部列")
                                            {
                                                for (int k = sht2.GetRow(j).FirstCellNum; k <= sht2.GetRow(j).LastCellNum; k++)//K为sht2的列数索引(或单元格索引)
                                                {
                                                    if (sht2.GetRow(j).GetCell(k) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                    {
                                                        string str2 = GetCellValue(sht2, j, k);
                                                        if (str2 == "")
                                                        {
                                                            continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                        }
                                                        else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                        {
    
                                                            if (IsContain(str1, str2))
                                                            {
                                                                WriteToDateGridView(i, j, str1, str2);  //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                                ListAdd(i);//将匹配的行数存入集合中
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                    }
                                                }
                                            }
                                            else    //如果sheet2选择了列,则不搜索全部列,只搜索选择的列,可以大大减少搜索次数,提高搜索速度
                                            {
                                                if (sht2.GetRow(j).GetCell(comboBox_list2.SelectedIndex - 1) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                {
                                                    string str2 = GetCellValue(sht2, j, comboBox_list2.SelectedIndex - 1);
                                                    if (str2 == "")
                                                    {
                                                        continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                    }
                                                    else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                    {
    
                                                        if (IsContain(str1, str2))
                                                        {
                                                            WriteToDateGridView(i, j, str1, str2); //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                            ListAdd(i);//将匹配的行数存入集合中
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                }
                                            }
    
                                        }
                                        else
                                        {
                                            continue;
                                        }
    
                                    }
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString() + "\r\n" + "1.请检查是否选择文件!" + "\r\n" + "2.请检查文件的sheet和列是否选择正确!", "错误提示"); //抛出异常信息
                }
            }
            private void Btn_Clear_Click(object sender, EventArgs e)
            {
                dataGridView1.Rows.Clear();//清除dataGridView1表格数据
                matchRow.Clear();//清空集合matchRow中的数据
                progressBar1.Value = 0;//将进度条数据置零
                progressBar1.Visible = false;//隐藏进度条
                lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比
                btn_SaveSearchResult.Enabled = false;//让“保存搜索结果”按钮无效
                btn_CreateResultExcel.Enabled = false;//让“生成备件清单”按钮无效
                //button1.Visible = true;
            }
    
            /// <summary>
            /// 将搜索结果显示到dateGridView里
            /// </summary>
            /// <param name="i">str1所在的行数</param>
            /// <param name="j">str1所在的行数</param>
            /// <param name="str1">sheet1中的字符串</param>
            /// <param name="str2">sheet2中的字符串</param>
            private void WriteToDateGridView(int i, int j, string str1, string str2)
            {
                int index = this.dataGridView1.Rows.Add();
                this.dataGridView1.Rows[index].Cells[0].Value = (index + 1).ToString();
                this.dataGridView1.Rows[index].Cells[1].Value = "第" + (i + 1).ToString() + "行";
                this.dataGridView1.Rows[index].Cells[2].Value = str1;
                this.dataGridView1.Rows[index].Cells[3].Value = "第" + (j + 1).ToString() + "行";
                this.dataGridView1.Rows[index].Cells[4].Value = str2;
            }
    
            private string GetCellValue(NPOI.SS.UserModel.ISheet sht, int i, int j)
            {
                string str = "";//声明字符串变量str2
                string cell_Type = sht.GetRow(i).GetCell(j).CellType.ToString();//获取sht2第j行,第k列单元格的数据格式,并赋值给字符串变量cell_Type2 
                switch (cell_Type)    //根据单元格里的数据格式读取数据的值;
                {
                    case "String":
                        str = sht.GetRow(i).GetCell(j).StringCellValue;//按字符串格式读取单元格数据的值
                        break;
                    case "Numeric":
                        str = sht.GetRow(i).GetCell(j).NumericCellValue.ToString();//按数值格式读取单元格数据的值
                        break;
                }
                return str;
            }
    
    
            private void Btn_SaveSearchResult_Click(object sender, EventArgs e)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = "Excel files (*.xls)|*.xls";
                saveFileDialog.FilterIndex = 0;
                saveFileDialog.RestoreDirectory = true;
                saveFileDialog.CreatePrompt = true;
                saveFileDialog.Title = "导出Excel文件到";
    
                DateTime now = DateTime.Now;
                saveFileDialog.FileName = "搜索结果" + "-" + DateTime.Now.ToLongDateString().ToString() + "-" + now.Hour.ToString().PadLeft(2, '0') + "时" + now.Minute.ToString().PadLeft(2, '0') + "分" + now.Second.ToString().PadLeft(2, '0') + "秒";
                saveFileDialog.ShowDialog();
    
                this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                this.dataGridView1.MultiSelect = false;
    
                Stream myStream = saveFileDialog.OpenFile();
                StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding("gb2312"));
                string str = "";
                try
                {
                    //写标题     
                    for (int i = 0; i < this.dataGridView1.ColumnCount; i++)
                    {
                        if (i > 0)
                        {
                            str += "\t";
                        }
                        str += this.dataGridView1.Columns[i].HeaderText;
                    }
                    sw.WriteLine(str);
                    //写内容   
                    for (int j = 0; j < this.dataGridView1.Rows.Count; j++)
                    {
                        string tempStr = "";
                        for (int k = 0; k < this.dataGridView1.Columns.Count; k++)
                        {
                            if (k > 0)
                            {
                                tempStr += "\t";
                            }
                            if (this.dataGridView1.Rows[j].Cells[k].Value != null)
                            {
                                tempStr += this.dataGridView1.Rows[j].Cells[k].Value.ToString();
                            }
                            else
                            {
                                continue;
                            }
    
                        }
                        sw.WriteLine(tempStr);
                    }
                    sw.Close();
                    myStream.Close();
                    if (File.Exists("搜索结果" + "-" + DateTime.Now.ToLongDateString().ToString() + "-" + now.Hour.ToString().PadLeft(2, '0') + ":" + now.Minute.ToString().PadLeft(2, '0') + ":" + now.Second.ToString().PadLeft(2, '0')))
                    {
                        MessageBox.Show("搜索结果保存成功!保存路径与原文件路径相同!", "保存提示");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    sw.Close();
                    myStream.Close();
                }
            }
    
            /// <summary>
            /// “生产备件清单”按钮的的单击事件,根据匹配成功的行数,删除匹配成功的行数,生成备件清单(匹配成功的表示库房已经有这个备件,则该备件不需要采购,所以将其删除后,剩下的即为备件清单)
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Btn_CreateResultExcel_Click(object sender, EventArgs e)
            {
            string ResultPath = System.IO.Path.GetDirectoryName(FilePath1) +"\\"+ "备件清单" + "-" + DateTime.Now.ToLongDateString().ToString()+".xlsx";//指定存储的路径           
                File.Copy(FilePath1, ResultPath, true);//三个参数分别是源文件路径,存储路径,若存储路径有相同文件是否替换
                int deleteTimes = 0;//记录删除行的次数,因为没删除一行,需要删除的行数索引就变了(减少了1)
                for (int i = 0; i <= matchRow.Count-1; i++)
                {
                    DeleteRows(ResultPath, (Int32)matchRow[i]+1-deleteTimes);
                    deleteTimes++;
                }
                //生成成功提示。
                if (File.Exists(ResultPath))
                {
                    MessageBox.Show("备件清单生成成功!保存路径与原文件路径相同!", "保存提示");
                }
                else
                {
                    MessageBox.Show("备件清单生成失败!", "保存提示");
                }
            }
    
            /// <summary>
            /// 删除Excel文件中的特定行(上移并覆盖)
            /// </summary>
            /// <param name="FilePath">需要删除的Excel文件全路径</param>
            /// <param name="rowIndex">需要删除的行数索引</param>
            private void DeleteRows(string FilePath, int rowIndex)//(Excel.Worksheet sheet, int rowIndex)
            {
                FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//必须要选择flieShare方式为ReadWrite,这样就可以在文件被打开的时候读取文件信息。
                NP.XSSFWorkbook wk = new NP.XSSFWorkbook(fs);//实例化一个.xlsx格式的工作簿
                NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(comboBox_sheet1.SelectedIndex);//根据“选择sheet”下拉列表框,获取工作表           
                sht.ShiftRows(rowIndex, sht.LastRowNum, -1);//将从第rowIndex行到最后一行的数据向上移动一行,即将rowIndex-1行删除了
                FileStream file = new FileStream(FilePath, FileMode.Create);//实例化一个FileStream文件
                wk.Write(file);//将file文件流写入wk工作簿
                file.Close();//关闭文件流
            }
    
            /// <summary>
            /// 判断matchRow里是否存在当前行索引号(因为文件1中的某一行可能搜索出多个相似结果,经过判断后可以避免重复存入相同的行数到matchRow中,导致生成备件清单时删除错误)
            /// </summary>
            /// <param name="i">当前行索引号</param>
            private void ListAdd(int i)
            {
                if (!matchRow.Contains(i))//判断集合matchRow中是否包含i
                {
                    matchRow.Add(i);//如果不包含,则将i添加到matchRow中
                }
                else
                {
                    return;//如果包含,则返回
                }
            }
    
            private void Located()//(string filePath,)
            {
                string excelName = FilePath1;//你的excel文件的位置
                string sheetName = "sheet1";//你的sheet的名字
                string strStart = "A100";//起始单元格
                string strEnd = "B200";//结束单元格
                object missing = Type.Missing;
                Excel.Application excel = new Excel.Application();
                Excel.Workbook book = excel.Workbooks.Open(excelName, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
                Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets[sheetName];
                excel.Application.Goto(sheet.Range[strStart, strEnd], true);
                excel.Visible = true;
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                this.Resize += new EventHandler(Form1_Resize);
                X = this.Width;
                Y = this.Height;
                setTag(this);
                Form1_Resize(new object(), new EventArgs());
            }
            //***控制控件大小及文字大小开始***//
            private float X;
            private float Y;
            private void setTag(Control cons)
            {
                foreach (Control con in cons.Controls)
                {
                    con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
                    if (con.Controls.Count > 0)
                        setTag(con);
                }
            }
            private void setControls(float newx, float newy, Control cons)
            {
                foreach (Control con in cons.Controls)
                {
                    string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
                    float a = Convert.ToSingle(mytag[0]) * newx;
                    con.Width = (int)a;
                    a = Convert.ToSingle(mytag[1]) * newy;
                    con.Height = (int)(a);
                    a = Convert.ToSingle(mytag[2]) * newx;
                    con.Left = (int)(a);
                    a = Convert.ToSingle(mytag[3]) * newy;
                    con.Top = (int)(a);
                    Single currentSize = Convert.ToSingle(mytag[4]) * Math.Min(newx, newy);
                    con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                    if (con.Controls.Count > 0)
                    {
                        setControls(newx, newy, con);
                    }
                }
            }
            void Form1_Resize(object sender, EventArgs e)
            {
                float newx = (this.Width) / X;
                float newy = this.Height / Y;
                setControls(newx, newy, this);
                //this.Text = "窗体尺寸:" + this.Width.ToString() + " " + this.Height.ToString();
            }
            //***控制控件大小及文字大小结束***//
    
    
            private void Button1_Click(object sender, EventArgs e)
            {
                Located();            
            }
    
            private void DataGridView1_DoubleClick(object sender, EventArgs e)
            {
                //Located();
            }
    
            private void Btn_Help_Click(object sender, EventArgs e)
            {
                using (Form_Help dlg = new Form_Help()) //Form_Help是窗口类名,确保访问;后面的是构造函数
                {
                    dlg.ShowDialog();
                }
            }
    
            private void Btn_Stop_Click(object sender, EventArgs e)
            {
                flag_SearchStop = true;
            }
        }
    }
    
    
    展开全文
  • 在几百几千个数据中发现重复项 统计互不相同的数据个数 多个工作表的单元格合并计算 单个单元格中字符统计 数据区包含某一字符的项的总和,该用什么公式 函数如何实现分组编码 【数值取整及进位】 取整数函数 数值...
  • EXCEL函数公式集

    热门讨论 2010-03-16 03:26:38
    在几百几千个数据中发现重复项 统计互不相同的数据个数 多个工作表的单元格合并计算 单个单元格中字符统计 数据区包含某一字符的项的总和,该用什么公式 函数如何实现分组编码 【数值取整及进位】 取整数函数 数值...
  • Java编程思想(完整版)

    2012-02-13 00:13:57
    1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类: 尽管extends关键字暗示着我们要为接口“扩展”新功能,但实情并非肯定如此。为区分我们的新类,第二个办法是改变基础类一个现有函数的行为。我们将其...
  • 第1章 怎样才能制作出优秀的幻灯片 1.1 这些细节你注意了吗 1.2 这些问题你碰到过吗 1.2.1 文字过多的幻灯片 1.2.2 文本中应用过多效果的幻灯片 1.2.3 滥用渐变效果的幻灯片 1.2.4 画面比较混乱的幻灯片 1.2.5 只...
  • 实例065 ListView列表拒绝添加重复信息 78 实例066 将数据库数据添加到ListView控件 80 实例067 用ListView控件制作导航界面 81 实例068 在ListView控件中对数据排序或统计 83 实例069 在ListView控件中...
  • 代码语法错误分析工具pclint8.0

    热门讨论 2010-06-29 07:00:09
    由于PC-LINT对于一般程序员来说可能比较陌生,有好多人安装了也不知道怎样配置和使用。 下面我就根据自己的安装和配置心得对PC-Lint的安装、配置及使用进行下详细说明.本人主要介绍了将PC-Lint集成到VC++6.0和...
  • 测试培训教材

    2014-04-01 12:10:48
    注:由于Cruise Booking的测试是由Cruise Booking的需求转化而成的,所以需求覆盖中默认就覆盖了Cruise Booking的需求 添加对“View Reservations”需求的覆盖 -- Linking Tests to a Requiremnet 将测试...
  • 正则表达式

    2014-12-03 14:51:39
    怎样实现? [JAVA] javascript 正则表达式 秋雨叶 发表于 2004-12-9 14:54:13 正则表达式是一个描述字符模式的对象。 JavaScript的RegExp对象和String对象定义了使用正则表达式来执行强大的模式匹配...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    编码转换,怎样实现将GB2312编码的字符串转换为ISO-8859-1编码的字符串。 9.Java中访问数据库的步骤,Statement和PreparedStatement之间的区别。 10.找出下列代码可能存在的错误,并说明原因: 二、JSP&Servlet...
  •  实例070 在列表视图中拖动视图 85  实例071 用ListView控件选取整行数据 88  实例072 用ListView控件开发登录界面 89  2.8 TreeView控件应用 91  实例073 将数据库数据显示到树视图中 91  实例...
  •  ◇ 详细设计说明书:着重描述每一模块是怎样实现的,包括实现算法、逻辑流程等。  ◇ 用户操作手册:本手册详细描述软件的功能、性能和用户界面,使用户对如何使用该软件得到具体的了解,为操作人员提供该软件...
  • C#.net_经典编程例子400个

    热门讨论 2013-05-17 09:25:30
    74 实例064 利用选择控件实现复杂查询 76 2.7 ListView控件应用 78 实例065 ListView列表拒绝添加重复信息 78 实例066 将数据库数据添加到ListView控件 80 实例067 用ListView控件制作导航...
  • flash shiti

    2014-03-14 10:32:41
    43.下图中哪几可以打开平滑与整平工具? A. 从附属选项中挑选 和 钮 B. 从附属选项中挑选 和 钮 C. 选取Insert菜单下的Smooth命令和Straighten命令 D. 选取Modify菜单下的Smooth命令和Straighten命 44.如何使...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 捕获屏幕...
  • C#程序开发范例宝典(第2版).part02

    热门讨论 2012-11-12 07:55:11
    实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • C#程序开发范例宝典(第2版).part13

    热门讨论 2012-11-12 20:17:14
    实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...
  • 实例165 在图像文件中实现自定义标记 232 实例166 获取指定点的RGB值 234 4.9 图像工具 235 实例167 获取图片类型 235 实例168 简单画图程序 236 实例169 看图工具 239 实例170 文字保存为图片 240 实例171 ...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

怎样标记重复项