注册 登录
Office中国论坛/Access中国论坛 返回首页

ganlinlao的个人空间 http://www.office-cn.net/?230471 [收藏] [复制] [分享] [RSS]

日志

Access迈向Web化第二步:html与winform交互

热度 2已有 3322 次阅读2015-12-9 10:37 |个人分类:access入门| 编程语言, 办不到, 文章, 而且

这篇文章可能会写很久,很久。
在vba中不要试图全面控制Webbrowser,因为那是用vba办不到,即使能办到也一定是办不好的事情。
而且全面控制webbrowser的复杂度会大大超出你的意料。
可以说在所有使用webbrowser的编程语言中,vba调用是最简便的一种。
html与winform的交互,主要是两种类型的交互。一种是html(js)与vba函数的互相调用,一种是html(js)与recordset的数据交互
一、html(js)如何与vba函数互相调用?
       vba通过html的dom,可以全面读写html和js,这是很容易做到的。但html或js如何调用vba函数呢?
        主要有两种方式:
        1、通过事件,来通知winform执行vba函数。
             引用microsoft html object libray类型库      
              Dim WithEvents m_Doc As MSHTML.HTMLDocument
              Private Sub Form_Load()
              Me.WebBrowser1.Navigate2 "http://www.baidu.com"
              End Sub
              Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
            Set m_Doc = Me.WebBrowser1.Document
             End Sub
              Private Function m_Doc_onclick() As Boolean
              Dim elem As IHTMLElement   
             Set elem = m_Doc.parentWindow.event.srcElement
             select case elem.id      '这其实是一个事件列表
              case id1
              call  mySub1
              case id2
              call  mysub2
               ……
              end select
            End
            这里重点用到的是Dom的window.event对象,并且主要是用到srcElement属性。           
            使用 window.event 对象,可以捕获 WebBrowser 众多的鼠标和键盘事件,如鼠标坐标、按   下了键盘哪个键,以及键盘 Ctrl、Alt、Shift 键的状态、当前网页元素的ID、索引等等。 
            可以说这是VBA与webbrowser交互的唯一简便途径了。
          这种方式的缺点:
          (1)、必须为每一个htm页面写特定的事件列表,虽然这当中最主要是onclick事件。
          它的抽象度非常差。如果你有什么更好的方式,不妨提出来讨论一下。
          (2)、WebBrowse 控件的 event 对象只能捕捉主页面的有关事件,对网页包含的内嵌网页和框架无能为力。要捕捉内嵌网页和框架的有关事件,必须为每个网页定义一个捕捉事件,但 VBA 的 WithEvents 语句并不支持定义数组事件。
        这里很容易转换成另一个问题:如何让withEvents支持collection或数组?这个问题的答案,能解决的事情范围变得很大了,如access的mdi问题等。

        2、通过window.external来调用vba函数
       通过window.external调用vba函数,其实是比较理想的方式,所有的ie的activeX插件,几乎都是通过这种方式。但 Webbrowser只有在实现IDocHostUIHandler接口后,window.external才能调用VBA函数。
       这在vb6中可以做到,但在access中办不到,因为它必须引用olelib.tlb,而access本身没有任何编译功能。( 写到这里,我忍不住想起mde,accde,这种编译其实是彻头彻尾的骗人小把戏)
       很可惜,这种方式只能放弃了。
        表面看起来,似乎缺陷蛮多的,功能有限,但别忘了我们在Access中使用html,并不是想用html来全面替代winform的功能,因为这不科学,也完全没必要。所以还是可以承受的。不要以为用c++,c#、vb.net调用webbrowser会更容易,坦白地说,它们只会带来更多的麻烦和痛不欲生的折磨而已。也不要以为用webkit会更容易,那是永远不可能的。

二、数据交互:
    准备好几种工具:
   1、 json的vba版解析器
在html5时代,不管你见或不见,json就在那里,不远、不近,
你回避不了。所以了解json格式是必须的,很容易在网络上搜到几十种vb6版或asp版的json解析器。它们都很方便。挑一种符合你使用的,或有人最近两三年还在维护的json解析器。
  

发表评论 评论 (4 个评论)

回复 roych 2015-12-9 17:00
JavaScript调用VBA函数从来都是一件出力不讨好的事情。一方面必须要考虑到IE内部的安全机制,另一方面还需要考虑事件如何被识别。我现在已经放弃这方面的尝试了。
回复 ganlinlao 2015-12-9 17:37
我现在还没很深入进去,但个人估计javascript调用vba函数的场合,应该很少的。具体涉及到的情景:
1、点击提交时,winform要能够捕获到submit按钮被点击,从而从Html获取数据。
     数据验证还是交给js去做。这个应该可以通过事件冒泡顺序来让js验证先执行。
2、winform应该具有获取xmlhttpRequrest事件的能力。也就是它要开始要发送数据时,能够从dom中获取它的数据,解析json数据,从数据库查询到recordset系列化成json格式推送给xmlhttp。(之所以这样,是因为很多框架会默认通过xmlhttp来获取数据,这样可以无须改动框架)这个是重点要解决的问题
3、用html作菜单时,这个用到vba函数可能会多一些。
总体的原则,还是界面处理交给javascript处理,vba只负责数据接收和推送
回复 admin 2015-12-22 08:29
有一定的前景,但主要是IE现在没有了,可能会受到一定的影响
回复 ganlinlao 2015-12-24 12:28
ie11的前景无须我们太多关心,至少在接下来的10年,它会一直存在。IE的消失对c#的冲击是最大的。很多的c#人不停向微软追问webbrowser问题,强烈要求微软至少要提供Edge的接口。目前微软的Edge没有对c#、c++提供接口,而是对内部的javascript提供了一个webview接口。只要edge对外提供接口,那vba肯定能用得了,毕竟edge还是c++写的。肯定会有人提供edge的tlb的。

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-11-5 02:33 , Processed in 0.083519 second(s), 18 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回顶部