VB6何以长盛不衰

微软刚刚将其 Windows 系统对 Visual Basic 6 程序的完全兼容支持延长到了 Windows 8 的整个产品周期. Visual Basic 6 最早发售于 1998 年, 所以现在来看 VB6 程序将至少被支持 24 年. 相比之下 .NET Framework 1.1 (2002 年发行) 则仅仅被支持了 7 年, 到了 Windows 7 (2009) 便被微软抛弃了.

我的一个学生曾经开玩笑说过 Visual Basic 6 就像 Windows 环境中“杀不死的小强”. 实际上这个比喻不无道理 - 蟑螂生存的秘诀在于它的简单, 它们所做的所有事情就是在自己占据的角落里坚持活下去, 除此之外什么都没有. 同样, Visual Basic 6 也满足了开发者为它预设的市场的所有需求——允许经验不多的程序员快速开发简单的程序. Visual Basic 从未被当作一种提供给专业程序员开发复杂程序的语言.
Visual Basic 6 实现其价值的方式是将 Windows 的各种复杂之处简化, 因此简单的工作对于 VB 来说非常容易完成. 不过另一方面, 相对复杂的工作比如使用线程则基本是不可能的. 对我来说有一个经验规则很有用:VB 中, 用了十分钟实现不了的功能对我来说肯定是没法实现的. 此外 VB 成功的另一个关键之处是由于其提供的功能较少, 所以所需的学习时间和学习难度也较低. 举个例子说, 就是学习开巴士需要的时间显然比学习怎么开战斗机少, 而成为一个优秀的 Visual Basic 程序员需要的时间也显然比成为一个优秀的 C++ 程序员少; 而当时 Visual Basic 6 面对的主要同类对手就是 C++.
不过到了 Visual Basic .NET 时代微软显然没有意识到这些. 当 VB .NET 成为一个所谓“全功能语言”的时候, 微软的开发者为它加上了 C# 所拥有的所有高级和复杂的功能 —— 线程, 多态继承, 等等. 也因此 VB .NET 变成了一个和 C# 要求相同的技能, 相同的学习过程和给人完全相同体验的编程语言. 当然这并不完全是微软的判断失误: 微软员工其实做了他们认为 Visual Basic 开发者们要求他们做的事情, 满足了 VB6 用户的要求.
但对于 Visual Basic 来说, 用“沉默的大多数”来描述大部分开发者非常合适. 几乎所有的 Visual Basic 6 用户都对现在的产品非常满意——沿用我们前面所使用的比喻, 他们很愿意只做公交司机: 每天五点下班回家, 不用加班到半夜; 周末在家和家人在一起而不用回到办公室; 晚上和配偶在一起, 而不是坐在办公室里带着充满血丝的眼睛连夜编程, 早上吃着昨天剩下的冷饭. 他们并不在意 Visual Basic 6 既没有提供运算符重载也不提供完整的面向对象模型, 所以他们没有抱怨什么.
而微软听到的声音则来自 3% 愿意成为战斗机驾驶员的 Visual Basic 6 公交司机——他们在闲暇时间参加业内会议, 在网上论坛中提问, 给各种关于 VB 的文章写自己的回复. 而也是这些人不能满足只在幻想中发射导弹击毁刚刚别了他们巴士的轿车——他们真的去向微软要求新的巴士必须带着和战斗机一样的加力燃烧室, 两边挂着格斗导弹, 车尾带上干扰弹发射器, 驾驶座还要有平视显示器. 因为他们是 Visual Basic 开发者中喊话声音最大的一群, 所以微软照做了.
于是到最后, 将 Visual Basic .NET 交给熟悉了 Visual Basic 6 的大部分程序员就如同人施放魔法将一只宠物狗仅仅在生理上变成了丛林狼, 然后便对着它大喊“去林子里抓只羊回来!”适应了宠物狗生活的狼显然会这么想“哈? 您没事儿吧? 我哪儿也不去就在这儿带着等你给我开罐头.”于是 Visual Basic 6 程序员依然如故.
当然 Visual Basic 6 也并非完美无缺. 最好的例子可能就是 On Error Resume Next 了——在工作的时候某一步执行出问题了, 所以我们继续按原计划该干什么干什么然后看看结果什么样? 想想都知道这明显不合理. 然而我们仍然应该记住由技能较低 (所以便宜) 的开发人员对功能有限 (便宜) 的程序进行快速 (便宜) 开发能解决很大一部分实际生产中遇到的问题, 而 Visual Basic 6 是这种情景中一种优秀的工具.
Visual Basic 6 解决的问题并不会凭空消失, 所以到微软提供一种可以替代 VB6 的工具前, Windows 系统中的小强还是会继续顽强的生存下去. 我愿意赌五块钱, 就算到了 Windows 9 还是 Windows 10, 微软也还是必须提供 Visual Basic 兼容.

Visual Studio 2012 Express 将免费发布给桌面开发者

微软今天宣布用于Windows桌面应用开发的Visual Studio Express 2012版将完全免费发布。之前微软曾经将Windows桌面应用的开发工作交给Visual Studio 2012专业版来完成,可以实现Metro应用、Web应用、Azure云应用和Windows Phone应用,售价400美元,而现在看来Visual Studio Express的功能已经可以覆盖到桌面应用,而且不需要付费。

微软将Express产品定位给Windows程序开发爱好者、初学者和开源的开发者,可实现命令行和桌面应用程序的开发,让他们可以在更低的成本下开始工作。

Google发布可视化编程语言Blockly

Google发布了完全可视化的编程语言 Google Blockly,类似 MIT 的儿童编程语言 Scratch,你可以通过类似玩乐高玩具的方式用一块块图形对象构建出应用程序。

每个图形对象都是代码块,你可以将它们拼接起来,创造出简单功能,然后将一个个简单功能组合起来,构建出一个程序。整个过程只需要鼠标的拖曳,不需要键盘敲击。该项目类似 Google 最近放弃的 App Inventor,不清楚 Blockly 与 App Inventor 或 Scratch 有何联系。

VB.Net将DataGridView中的内容保存为CSV文件

相关代码:

        <Extension()>
        Public Function ExportToCsv(dgv As DataGridView) As Boolean
            Dim dlg As New SaveFileDialog()
            dlg.Filter = "CSV(逗号分隔)(*.csv)|*.csv"
            dlg.FilterIndex = 0
            dlg.RestoreDirectory = True
            dlg.CreatePrompt = True
            dlg.Title = "保存为CSV(逗号分隔)文件"
            If dlg.ShowDialog() = DialogResult.OK Then
                Dim myStream As Stream
                myStream = dlg.OpenFile()
                Using sw As New StreamWriter(myStream, Encoding.Default)
                    Dim columnTitle As String = ""
                    Try
                        '写入列标题  
                        For i As Integer = 0 To dgv.ColumnCount - 1
                            If i > 0 Then
                                columnTitle += ","
                            End If
                            columnTitle += dgv.Columns(i).HeaderText
                        Next
                        columnTitle.Remove(columnTitle.Length - 1)
                        sw.WriteLine(columnTitle)
                        '写入列内容     
                        For j As Integer = 0 To dgv.Rows.Count - 1
                            Dim columnValue As String = ""
                            For k As Integer = 0 To dgv.Columns.Count - 1
                                If k > 0 Then
                                    columnValue += ","
                                End If
                                If dgv.Rows(j).Cells(k).Value Is Nothing Then
                                    columnValue += ""
                                Else
                                    Dim m As String = dgv.Rows(j).Cells(k).Value.ToString().Trim()
                                    columnValue += m.Replace(",", ",")
                                End If
                            Next
                            columnValue.Remove(columnValue.Length - 1)
                            sw.WriteLine(columnValue)
                        Next
                        sw.Close()
                        myStream.Close()
                    Catch e As Exception
                        Return False
                    Finally
                        sw.Close()
                        myStream.Close()
                    End Try
                End Using
                Return True
            Else
                Return False
            End If

使用方法:

在按钮单击事件中加入以下语句

DataGridView1.ExportToCsv

VBA使用正则表达式

通过菜单 工具 -> 引用 引用了Microsoft VBScript Regular Expressions 5.5 后就可以声明正则相关对象。主要有三个对象:RegExp、MatchCollection、Match。

示例代码:

Sub Test()
    Dim re As RegExp
    Dim mh As Match
    Dim mhs As MatchCollection
    Dim inpStr As String
    
    inpStr = "我的E-mail: me@lishewen.com 。"
    Set re = New RegExp
    re.Pattern = "(w+)@(w+).(w+)"
    Set mhs = re.Execute(inpStr)
    Set mh = mhs(0)                                      '只有一个匹配
    
    MsgBox "电子邮件地址是: " & mh.Value          '这里是匹配的内容
    MsgBox "用户名是:       " & mh.SubMatches(0)  '第一个括号中的内容
    MsgBox "邮箱是:         " & mh.SubMatches(1)  '第二个括号中的内容
    MsgBox "域名是:       " & mh.SubMatches(2)  '第三个括号中的内容    
End Sub

Outlook批量发送带附件的邮件

需求:

顺序读取指定文件夹中文件名,文件名的格式为“邮箱地址”+“空格”+“数字”
比如邮箱地址为a@126.com  指定目录中有文件名为 a@126.com.mp3  及a@126.com 1.mp3 (邮箱地址+空格+1)的两个音乐文件 则自动以附件方式发送两文件到a@126.com。
其中也可能只是一个邮箱地址,不包括空格和数字,从文件名中分析出邮箱地址,把该文件发送到该邮箱地址

解决方案:

制作Outlook插件实现

Outlook插件运行截图:

如需定制此类插件请联系我

Outlook发送邮件的VBA宏

Sub SendFile()
    Dim olApp As Outlook.Application
    Dim objMail As Outlook.MailItem
    Set olApp = ThisOutlookSession.Application
    Set objMail = olApp.CreateItem(olMailItem)
    With objMail
        .BodyFormat = olFormatPlain
        .Subject = "您的文件"
        .Body = "您的文件,请查收"
       '收件人
        .To = "lishewen@gmail.com"
        '抄送
        .CC = "me@lishewen.com"
        '附件
        .Attachments.Add "c:\算神\黎摄文.txt
        .Send
    End With
End Sub

VBA获取文件夹中的文件名的函数

'说明:获取指定文件夹中的文件
'参数:
'   path:字符串,指定的文件夹路径
'   searchOption:布尔值,True 所有文件; False 当前文件夹中的文件
'返回值:数组
'注意:数组第1项(GetFiles(0))始终为空,应从第2项(GetFiles(1))开始计算
Public Function GetFiles(path As String, searchOption As Boolean) As String()
    Dim result() As String
    Dim arr() As String
    Dim i, j As Integer
    
    arr = getFiles_(path, searchOption)
    For i = 0 To UBound(arr)
        If arr(i) <> "" Then
            j = j + 1
        End If
    Next
    If j > 0 Then '防止下标越界
        ReDim result(j) As String
        j = 1
        For i = 0 To UBound(arr)
            If arr(i) <> "" Then
                result(j) = arr(i)
                j = j + 1
            End If
        Next
    End If
    GetFiles = result
End Function

'本函数为私有函数,获取指定文件夹中的文件
'因返回的数组可能包含空元素,需由GetFiles进行过滤排除
Private Function getFiles_(path As String, searchOption As Boolean) As String()
    Dim oFso As FileSystemObject
    Dim oFolder, oFolder2 As Folder
    Dim oFile As File
    Dim i, j As Integer
    Dim list() As String
    ReDim result(0) As String
    
    Set oFso = CreateObject("Scripting.FileSystemObject")
    Set oFolder = oFso.GetFolder(path)
    
    '检查文件夹存在
    If Not oFso.FolderExists(path) Then
        getFiles_ = result
        Set oFile = Nothing
        Set oFolder2 = Nothing
        Set oFolder = Nothing
        Set oFso = Nothing
        Exit Function
    End If
    
    '当前文件夹中的文件
    If oFolder.files.Count > 0 Then
        ReDim Preserve result(oFolder.files.Count - 1)
        For Each oFile In oFolder.files
            result(i) = oFile.path
            i = i + 1
        Next
    End If
    
    '子文件夹中的文件
    If searchOption And oFolder.SubFolders.Count > 0 Then
        For Each oFolder2 In oFolder.SubFolders
            list = getFiles_(oFolder2.path, searchOption)
            i = UBound(result)
            ReDim Preserve result(i + UBound(list) + 1)
            For j = 0 To UBound(list)
                result(i + j + 1) = list(j)
            Next
        Next
    End If
    
    getFiles_ = result
    
    Set oFile = Nothing
    Set oFolder2 = Nothing
    Set oFolder = Nothing
    Set oFso = Nothing
End Function

VBA计时器Timer的使用

Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public lTimerID As Long

Sub Start()
    '启动计时器,时间间隔1分钟
    StartTimer 60000
End Sub

Sub StartTimer(lDuration As Long)
    If lTimerID = 0 Then
        lTimerID = SetTimer(0, 0, lDuration, AddressOf OnTime)
    Else
        Call StopTimer
        lTimerID = SetTimer(0, 0, lDuration, AddressOf OnTime)
    End If
End Sub

Private Sub StopTimer()
    KillTimer 0, lTimerID
End Sub

Private Sub OnTime()
    ' 计时器触发后运行的代码放在这
    ' ...
    SendFile "c:\abc"
    SendFile "c:\cba"
End Sub

Visual Studio速成版前途未卜

Visual Studio 速成版(Visual Studio Express)从来就不是一款免费产品。它的第一个版本发布于 2005 年,当时目标是成为一款入门级产品,并且售价大约 100 美元。为了建立产品用户群和促进 .NET 的发展,微软曾许诺第一年注册该产品的用户将可以免费获取。

该产品的推广活动开始于 2005 年 11 月 7 日,截止到 4 月 19 日共有超过 500 万份 VS Express 的拷贝被下载。见状,微软觉得最好把该产品免费公开。当时共有 5 种可用的 VS 速成版本,它们是:Visual Basic、Visual C#、Visual J#、Visual C++ 和 Visual Web Developer。

虽然 Visual J#已经不复存在,但是其他版本都进行了更新并推出了 Visual Studio 2008 和 2010 版本。另外,新版本的 Windows PhoneXNA Game StudioRobotics Developer Studio 也随之发布。(后两者自从变为增件之后,需要依附于另外的 Visual Studio 速成版。)

《Visual Studio 产品指南》仅列出了以下版本:

  • 面向 Windows 8 的速成版(Express for Windows 8)
  • 面向 Web 的速成版(Express for Web)
  • 专业版(Professional)
  • 高级版(Premium)
  • 旗舰版(Ultimate)
  • 测试版(Test Professional)

目前,微软对于是否最终发布 Visual Studio 11 版本的C++、VB、C#和 Windows Phone 速成版尚未表态。