ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: weiyingde

[分享] 我的VBA自定义函数研习收获

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-2-7 22:16 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
你找他的帖子看看,我没有链接,他把自定义函数运用到具体代码中了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-2-13 22:01 | 显示全部楼层
本帖最后由 weiyingde 于 2019-3-17 19:25 编辑

4.提取指定类型的数据,或对夹杂有数字的单元格区域进行求和。
本函数有四个作用:
1、当 sr=“Gt”时,rng必须是单个的单元格,根据num的不同,有三个作用:
   (1)num=1 ,提取指定单元格中的汉字;
   (2)num=2,提取指定单元格中的英文字母;
   (3)num=3,提取指定单元格中的数字;
2、当 sr=“Sm”时,rng必须是单元格区域,num=3
    求指定单元格区域中所有所有数字的和。
代码如下:
Function 取数(rng As Range, sr As String, num As Integer, Optional ByVal fgf As String = "")
  Dim regEx, Mth, Matches         ' 建立变量。
  Dim Patrn$, Nnmb As Integer
  Numer = 0
Select Case sr
       Case "Gt"
            For Each rg In rng
                m = m + 1
            Next
            If m >= 2 Then
               MsgBox "取数(单元格引用,sr, num) " & Chr(10) & "sr=Gt 单元格引用必须是单个的"
               取数 = "第一个参数错误"
               Exit Function
            End If
            Select Case num
               Case 1
                    Patrn = "[一-龥]"
               Case 2
                    Patrn = "[A-Za-z]"
               Case 3
                    Patrn = "[0-9]{1,}"
               Case Else
                    MsgBox "取数(字符串或单元格引用,sr, num) " & Chr(10) & " num=1 提取汉字" & Chr(10) & " num=2 提取字母" & Chr(10) & " num=3 提取数字"
                    取数 = "第三个参数错误"
                    Exit Function
            End Select
            Set regEx = CreateObject("vbScript.regexp") 'New RegExp  ' 建立正则表达式。
            regEx.Pattern = Patrn    ' 设置模式。
            regEx.IgnoreCase = True  ' 设置是否区分大小写。
            regEx.Global = True      ' 设置全局替换。
             'regEx.MultiLine = True  '设置多行匹配。
            Set Matches = regEx.Execute(rng.Text) ' 执行搜索。
               If num = 1 Or num = 2 Then
                   For Each Mth In Matches         ' 遍历 Matches 集合。
                      RetStr = RetStr & fgf & Mth
                   Next
                   ss = Mid(RetStr, Len(fgf) + 1)
               Else
                   ss = Matches(0)
               End If
               取数 = IIf(num = 3, Val(ss), ss)
               Set regEx = Nothing
               ss = ""
       Case "Sm"
            If num <> 3 Then
               MsgBox "取数(字符串或单元格引用,sr, num) " & Chr(10) & " sr=Sm 区域数字求和" & Chr(10) & " num=3(必须为3)"
               取数 = "第三个参数错误"
               Exit Function
            End If
            For Each rg In rng
                n = n + 1
            Next
                If n = 1 Then
                   MsgBox "取数(单元格引用,sr, num) " & Chr(10) & "当sr=Sm时 单元格引用必须是区域的"
                   取数 = "第一个参数错误"
                   Exit Function
                End If
            For i = 1 To n
               ss = ss & rng.Item(i).Text
            Next
               Set regEx = CreateObject("vbScript.regexp") 'New RegExp  ' 建立正则表达式。
               regEx.Pattern = "[0-9]{1,}"    ' 设置模式
               regEx.IgnoreCase = True  ' 设置是否区分大小写。
               regEx.Global = True      ' 设置全局替换。
               'regEx.MultiLine = True  '设置多行匹配。
               Set Matches = regEx.Execute(ss) ' 执行搜索。
               For Each Mth In Matches
                 Numer = Numer + Val(Mth)
               Next
               取数 = Val(Numer)
               Set regEx = Nothing
               Set Matches = Nothing
      Case Else
           MsgBox "取数(单元格引用,sr, num)第二参数只能是:" & Chr(10) & "sr = Gt" & Chr(10) & "sr = Sm"
           取数 = "第二个参数错误"
           Exit Function
       n = 0: m = 0: ss = ""
End Select
End Function


再加上一个Function f_sum(a As String) As Double
   Dim dis As Object, b As Variant
   Application.Volatile
   Set dis = CreateObject("vbscript.regexp")
      With dis
         .Global = True
         .Pattern = "\-?\d+\.?\d*"
         If .test(a) Then
            For Each b In .Execute(a)
              f_sum = f_sum + Val(b)
            Next b
         End If
      End With
End Function

示例附件如下:





补充内容 (2019-10-20 12:37):
附香川群子的函数如下:
Function TQ(txt$, Optional k = 0, Optional pt = 1, Optional s$ = "")
    If IsNumeric(pt) Then pt = Choose(pt, "\w", "[^a-zA-Z]", "\D", "[^a-z]", "[^A-Z]", "\W", "\d")
    With CreateObject("VBScript.RegExp")
        .Global = True
        .Pattern = pt
        If .test(txt) Then
            If k = 0 Then
                TQ = .Replace(txt, s)
            ElseIf k > 0 Then
                If InStr(k, ".") Then
                    Set Ma = .Execute(txt)
                    ReDim a(Ma.Count - 1)
                    For Each m In Ma
                        a(c) = m
                        c = c + 1
                    Next
                    If s = "" Then s = " "
                    TQ = Join(a, s)
                Else
                    TQ = .Execute(txt)(k - 1) '.Execute(txt)(0)
                End If
            Else 'If k < 0 Then TQ = .Execute(txt)(0).SubMatches(1)
                If InStr(k, ".") Then
                    TQ = .Execute(txt)(Int(-k) - 1).SubMatches(Mid(k, InStr(k, ".") + 1) - 1)
                Else
                    Set sMa = .Execute(txt)(-k - 1).SubMatches
                    ReDim a(sMa.Count - 1)
                    For Each m In sMa
                        a(c) = m
                        c = c + 1
                    Next
                    If s = "" Then s = " "
                    TQ = Join(a, s)
                End If
            End If
        Else
'            Stop
            If k = 0 And s = "" Then TQ = txt Else TQ = ""
        End If
    End With
End Function


补充内容 (2019-10-31 18:44):
Public Function HZGet(ByVal strscr As String) As String
    Dim i As Integer
    For i = 1 To Len(strscr)
        '汉字小于ASC值0﹐否则在0-127之间
        If Asc(Mid(strscr, i, 1)) < 0 Then
            HZGet = HZGet & Mid(strscr, i, 1)
        End If
    Next i
    HZGet = HZGet
End Function

补充内容 (2019-10-31 18:46):
函数作用:字符型转数字型
'################################################################

Private Function TxtCData()
    Dim Sel As Range
    Dim TRow As Long, BRow As Long
    Dim LCou As Long, RCou As Long
   
    Set Sel = Range(Selection.Address)
   
    TRow = Sel.Row
    BRow = TRow + Sel.Rows.Count - 1
   
    LCou = Sel.Column
    RCou = LCou + Sel.Columns.Count - 1
   
    For C = LCou To RCou
        For R = TRow To BRow
            If Cells(R, C).NumberFormatLocal = "@" And IsNumeric(Cells(R, C).Value) = True Then
                Cells(R, C).NumberFormatLocal = "G/通用格式"
                If Cells(R, C).Value <> vbNullString Then _
                         Cells(R, C).Value = Val(Cells(R, C).Value)
            End If
        Next
    Next
    Set Sel = Nothing
End Function

单元格提取(或区域中数字求和).rar

20.04 KB, 下载次数: 40

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-2-26 15:10 | 显示全部楼层
本帖最后由 weiyingde 于 2019-2-26 15:14 编辑

5.删除指定符号的内容。说明:此程序借鉴liulang0808的原创,见http://club.excelhome.net/thread-1462567-1-1.html,五楼。
Function KillBrace(rng As Range, num As Integer)
Dim sr As String
With CreateObject("Vbscript.regexp")
    Select Case num
          Case 1: sr = "{.*?}"
          Case 2: sr = "【.*?】"
          Case 3: sr = "\[.*?\]"
          Case 4: sr = "\(.*?\)"
          Case 5: sr = "\(.*?\)"
          Case 6: sr = "<.*?>"
          Case 7: sr = "《.*?》"
          Case 8: sr = "{.*?}|【.*?】|\[.*?\]|\(.*?\)|\(.*?\)|<.*?>|《.*?》"
   End Select
   .Pattern = sr
   .Global = True
   KillBrace = .Replace(rng.Value, "")
End With
End Function


补充内容 (2020-5-27 09:16):
Case 9: sr = "[\((\))一-隝]"

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-4-17 22:13 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
6.获取汉字的笔画数。
’说明:此函数是别人的成果,丢失作者名字,实为遗憾。
Function BH_4(Hz$)
'Debug.Print Asc(Hz)
'   URL = "http://zidian.cibiao.com/zi_u" & Right(Application.Dec2Hex(AscW(Hz)), 4) & ".html"
     URL = "http://www.hifang.net/01xinhua/show.asp?q=" & GetUTF(Hz)
'  With CreateObject("WinHttp.WinHttpRequest.5.1") '

     With CreateObject("MSXML2.ServerXMLHTTP")
    Debug.Print URL
         .Open "GET", URL, False
         .Send
        Application.Wait Now + TimeValue("00:00:01")
        V = .responsetext
    Debug.Print V
' On Error Resume Next
       VV = Split(Split(V, "总笔画:<span class=""diczx4"">")(1), "<")(0)
       BH_4 = VV
    End With
End Function

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-4-17 22:18 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
再发一同样是笔画的,亦为他人成果,特此说明。
Function 笔画1(Hz$) As Integer
'URL = "http://www.hydcd.com/zidian/hz/13720.htm"
URL = "http://www.hifang.net/01xinhua/show.asp?q=" & GetUTF(Hz)
'    URL = "https://www.qqxiuzi.cn/hanyu/zidian/?zi=" & GetUTF(Hz)
'   URL = "http://www.hydcd.com/zidian/hz/" & GetUTF(Hz) & ".html"
'    URL = "https://hanyu.baidu.com/zici/s?wd=" & GetUTF(Hz) & "/"
'URL = "http://zidian.911cha.com/zi" & Application.Dec2Hex(AscW(Hz))
With CreateObject("MSXML2.ServerXMLHTTP")
'    With CreateObject("WinHttp.WinHttpRequest.5.1") '
         .Open "GET", URL, False
         .Send
Application.Wait Now + TimeValue("00:00:01")
V = .responsetext
'Debug.Print V, URL
'V = b2S(.ResponseBody, "GB2312")
VV = Split(Split(V, "总笔画:<span class=""diczx4"">")(1), "<")(0)
'VV = Left(Split(VV, "<td width='10%' >")(1), 2)
'         笔画1 = Split(Split(VV, "笔划:</td>")(1), "</td>")(0)
         笔画1 = VV
   '      笔画1 = Split(Right(Split(V, " 画<")(0), 3), ">")(1)
'      '   笔画1 = Left(Split(V, "总笔画数</dt>")(1), 53) ' ">")
         
     End With
End Function
'https://hanyu.baidu.com/zici/s?wd=%E6%83%B3

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-4-18 03:46 来自手机 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
虽然看不明白,不过正在努力学习

TA的精华主题

TA的得分主题

发表于 2019-4-18 10:19 | 显示全部楼层
获取汉字笔画数那个函数
我看懂了  是从网上抓取的
但  没提供转码函数的代码 对于新手来说 也是一头雾水,运行不成功的...

我这贴一下转码函数 也是收集于本论坛的
Function encodeURI(strText As String) As String
    Dim objDOM As Object
    Set objDOM = CreateObject("htmlfile")
    With objDOM.parentWindow
        objDOM.Write "<Script></Script>"
        encodeURI = .eval("encodeURIComponent('" & strText & "')")
    End With
    Set objDOM = Nothing
End Function

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-4-18 17:31 | 显示全部楼层
autolzg 发表于 2019-4-18 10:19
获取汉字笔画数那个函数
我看懂了  是从网上抓取的
但  没提供转码函数的代码 对于新手来说 也是一头雾水 ...

不错点赞,谢谢提醒,共同学习,一起提高。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-10-2 15:55 | 显示全部楼层
本帖最后由 weiyingde 于 2019-10-2 15:59 编辑

对数组进行汇总,并将生成的结果从高到低进行排列,最后一列为其名次。’此函数是在microyip大侠的帮助下完成,见http://club.excelhome.net/thread-1377426-2-1.html
再次表示感谢。
同时希望高人继续提供更好用的组数自定义函数。
Public Function 数组汇总(arr As Variant)
    Dim brr(), Dic As Object, a, r, j, i, l, tmp, crr
    Set Dic = CreateObject("Scripting.Dictionary")
    a = 1
    For j = 2 To UBound(arr)
        If Dic.Exists(arr(j, 1)) Then
            r = Dic(arr(j, 1))
            brr(2, r) = 1 + brr(2, r)
            brr(3, r) = brr(3, r) & j & ","
            brr(4, r) = arr(j, 6) + brr(4, r)
        Else
            ReDim Preserve brr(1 To 5, 1 To a)
            brr(1, a) = arr(j, 1)
            brr(2, a) = 1
            brr(3, a) = j & ","
            brr(4, a) = arr(j, 6)
            brr(5, a) = a
            Dic(arr(j, 1)) = a
            a = a + 1
        End If
    Next j
    For j = 1 To a - 1

        Dic.RemoveAll
        crr = Split(brr(3, j), ",")
        For i = 0 To UBound(crr) - 1
            Dic(arr(crr(i), 5)) = ""
        Next i
        brr(3, j) = Dic.Count
    Next j
   
    For j = 1 To a - 1
        For i = j + 1 To a - 1
            If brr(4, j) < brr(4, i) Then
               For l = 1 To 4
                    tmp = brr(l, i)
                    brr(l, i) = brr(l, j)
                    brr(l, j) = tmp
               Next l
            End If
        Next i
    Next j
    数组汇总 = Excel.Application.WorksheetFunction.Transpose(brr)
End Function

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-10-2 16:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 weiyingde 于 2019-10-2 16:44 编辑

随机获取指定路径下、文件名含有指定字符、指定类型的长文件名(即带有路径的文件名)或短文件名(不带路径和后缀的文件名)。
参数说明:
1、Fpth,为最末一级路径;
2、hzh,为文件类型,比如“.xlsx”,".gif",".jpg"等;
3、获取的文件名中带有指定字符。“课件”、“练习”等;
4、k为1,获取长文件名;为2,获取短文件名。
Public Function GetRnd(ByVal Fpth As String, ByVal hzh As String, ByVal Bhz As String, Optional k As Variant)
Dim MyDir$, ar(), n%
For Each f In CreateObject("scripting.filesystemobject").getfolder(Fpth).Files
    If Right(f.Name, Len(hzh)) = hzh And InStr(f.Name, Bhz) <> 0 Then
       n = n + 1
       ReDim Preserve ar(1 To n)
       Select Case k
              Case 1: ar(n) = f
              Case 2: ar(n) = Left(Split(f, "\")(UBound(Split(f, "\"))), Len(Split(f, "\")(UBound(Split(f, "\")))) - Len(hzh))
       End Select
    End If
Next
Randomize
GetRnd = ar(Int(Rnd * UBound(ar) + 1))
End Function



您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 12:45 , Processed in 0.042190 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表