用Microsoft BarCode Control 9.0控件显示条形码

条形码的编码等基本知识(百度百科)

Microsoft BarCode Control用在Access等开发环境中,可以进行数据绑定。绑定的目标属性是value。

Microsoft BarCode Control的value属性,是要编入条形码的信息字符串。

根据不同的编码规则,value要符合改规则规定的字符串形式,否则会显示一片空白。比如CODE 39编码,不能用小写字母;比如EAN-13编码,要用恰好13个数字,多了或者少了或者加入了字母,不是变白板就是变样(分割用的线没了)。

有的条码限制了大小尺寸,调也没用,比如EAN-13;有的可以调整。比如CODE 128

[微软] Microsoft BarCode Control的参考文档(CHM)下载

EMS单用的是CODE 39码。

Microsoft BarCode Control支持的编码方式包括

Style(样式) 0 - UPC-A 1 - UPC-E 2 - JAN-13 3 - JAN-8 4 - Casecode 5 - NW-7 6 - Code-39 7 - Code-128 8 - US Postnet 9 - US Postal FIM 10 - JP Post

Cross tabulation, Pivot table and OLAP Cube summarized by tools

Cross tab

Cross tabulation , is defined on WikiPedia as A cross tabulation (often abbreviated as cross tab) displays the joint distribution of two or more variables.

As below figures, the column values of the first table is transformed to column names in the second one, so the production of

 

 

Cross tabs are frequently used because:

  1. They are easy to understand. They appeal to people who do not want to use more sophisticated measures.
  2. They can be used with any level of data: nominal, ordinal, interval, or ratio - cross tabs treat all data as if it is nominal.
  3. A table can provide greater insight than single statistics.
  4. It solves the problem of empty or sparse cells.
  5. They are simple to conduct.

 

I think the cross-tab is really what the Relational Database means. That’s a meaningful “Relationships” between entities but not entity and it’s attributes.

Solution by SQL Server 2005

Code:

SELECT
    SalesPerson,
    [Oranges] AS Oranges,
    [Pickles] AS Pickles
FROM
    ( SELECT SalesPerson, Product, SalesAmount FROM tblSales ) ps
PIVOT
    (
      SUM (SalesAmount)
      FOR Product IN ( [Oranges], [Pickles])
    ) AS pvt

 

This most weak part of feature is that you must list all pivot column name manually. It’s pain.


BOL: Using PIVOT and UNPIVOT

SELECT < non-pivoted column>,
    [first pivoted column] AS ,
    [second pivoted column] AS ,
    ...
    [last pivoted column] AS
FROM
    (< SELECT query that produces the data>)
    AS
PIVOT
(
    < aggregation function>()
FOR
[< column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column],
    ... [last pivoted column])
) AS
< optional ORDER BY clause>;

Solution by MS Access

Microsoft Access provides a very nice cross table design wizard.

With the wizard, we get the cross-tab script based on JET-SQL.

TRANSFORM Sum(tblSales.SalesAmount) AS [Sum of SalesAmount]
SELECT tblSales.SalesPerson, Sum(tblSales.SalesAmount) AS [Total SalesAmount]
FROM tblSales
GROUP BY tblSales.SalesPerson
PIVOT tblSales.Product;

 

 

Pivot columns is automaticly generated and the aggregation over all pivot column can be produced. The JET-SQL is so smart and smoothly for small applications those don’t have to be scaled. You can use almost all VBA programming utilities in it. The TRANSFORM/PIVOT feature is powerful and more then 5 years before the SQL Server’s implementation.

It is based on JET-SQL, so not availible in an ADP project.

Solution by SQL Server 2000, CASE and GROUP

The classic solution of cross-tab in SQL Server 2000 or before is produced by CASE and GROUP.

select
    SalesPerson,
    SUM(CASE Product WHEN 'Pickles' THEN SalesAmount ELSE 0 END ) as [Pickles],
    SUM(CASE Product WHEN 'Oranges' THEN SalesAmount ELSE 0 END ) as [Oranges],
    SUM(SalesAmount)    as [Total Sales]
from
    tblSales
group by
    SalesPerson

We can find it’s footprint clearly in the SQL Server 2005’s pivot feature. And this is a base for other ideas.

Solution by SQL Server 2000, Dynamic SQL

Dynamic Cross-Tabs/Pivot Tables By Rob Volk

The basic idea is to generate dynamic CASE-and-GROUP based SQL statement and execute.

The following comments providing many improvement on this solution. i.e.

  • Introduce an WHERE statement as parameter for the @PivotColTable.
  • Using string to generate pivot columns but global temp table for better supporting of concurency calling.
  • Using user defined table with an user session column instead of global temp table.
  • To summarize multiple values.

There is also an similar solution I have not dived in, Dynamic Crosstab Queries, by Itzik Ben-Gan .

Solution by Excel

But the most easy and rich tool I have used is MS Excel’s pivot table.

Pivot table and OLAP Cube

The basic idea of OLAP Cube is a multi-dimession pivot table. The common visualization tool for OLAP is also a pivot table or pivot chart viewer. 

So, draw a figure to show basic concepts in OLAP by example metioned above as the END.

Structure searching supported compound database based on MS Access




Why based on MS Access

MS Access is wildly used, easily available and almost the most user friendly database product. I know many stuffs are working on MS Excel for compound information management and there exists such commercial solutions, the reasons coincide.

The solution described here is for

  • Small account of products catalog.
  • Fast development needed.
  • User interface and operation are crucial, or chemical information data is trivial part of the database.

Demonstration of functions


Platform and tools used

Solution step by step

  • Sample data

SDF files are downloaded directly from Pubchem ftp, it’s free and public.

  • Import SDF file into Access

As the structure description part (mol file) exists inside each compound, it’s not easy to parse the SDF file to csv and other table based format. I write a simple Python script to transform SDF file to Access accepted XML file. You can create a desired table in Access database and export it to XML format to get the XML template.

When data are ready, just run import command from Access.

You can also try RDkit to manipuate SDF and structure information in Python, it’s professional.

  • Generation of structure pictures

When transforming SDF file with Python, some further more actions be taken to generate BMP structure pictures.

Use Molconvert to convert the mol file into PNG format

os.system( “molconvert png %s/%s.mol -o %s/%s.png” %(folder, molid, folder, molid) )

Use PIL to convert PNG to BMP

Image.open( “%s/%s.png”%(folder, molid)).save(”%s/%s.bmp”%(folder,molid))

BMP pictures are needed because native Access only accepts BMP picture as OLE object and displayed on form control.

  • Embed Ole object with VBA

Public Sub load_img()
Me.Recordset.MoveFirst
While Not Me.Recordset.EOF
Me.pic.OLETypeAllowed = acOLELinked
Me.pic.SourceDoc = CurrentProject.Path & “img” & Me.cid & “.bmp”
Me.pic.Action = acOLECreateLink
Me.pic.SizeMode = acOLESizeStretch
Me.Recordset.MoveNext
Wend
End Sub

  • JME as structure query input

JME is a java package and I don’t know any way to combine it with Access directly. So an webcontrol is introduced to the Access form and JME embedded on the source page of the webcontrol. The dom object visit is more simple than I had imaged.

mol = Me.WebBrowser2.Document.applets.Item(0).MolFile()

  • Implentation of sturcture search function

This is truely the key technic of the solution. It is powered by opensourced checkmol/machmol. Acturally, just after read the usage part of source code of its dll version, I begun to think about to do something on Access. Access database uses JETSQL engine, it’s not as powerful as T-SQL, but it supports VBA functions. VBA code can easily visit exernal dll function, so JETSQL could be extended greatly.

So, the sturcture search code is really simple


select * from sample_data where MatchMol(query_mol, mol) > 0


MatchMol function is pre-defined by dll apis of checkmol/matchmol.

Code copied from MATCHMOLDLL.pas

——————————————————————————–
Private Declare Sub mm_SetMol Lib “matchmolDLL.dll” (ByVal st As String)
Private Declare Sub mm_SetCurrentMolAsQuery Lib “matchmolDLL.dll” ()
Private Declare Function mm_Match Lib “matchmolDLL.dll” (ByVal Exact As Boolean) As Long

Private Declare Function mm_GetRings Lib “matchmolDLL.dll” () As Long
Private Declare Function mm_GetAtomRing Lib “matchmolDLL.dll” (ByVal AtomNumber As Long) As Long
Private Declare Sub mm_Version Lib “matchmolDLL.dll” (ByVal st As String)

Public Function MatchMol(Needle As String, Haystack As String, Optional ExactMatch As Boolean = False) As Boolean
Static oldNeedle As String
If oldNeedle <> Needle Then
oldNeedle = Needle
mm_SetMol Needle
mm_SetCurrentMolAsQuery
End If

mm_SetMol Haystack
If mm_Match(ExactMatch) <> 0 Then MatchMol = True

End Function
——————————————————————————–

Performance issues

As a small database, there are about 2700 compounds are imported.

  • Ole picture in BMP format consumes much space. The database file size grows to 600MB.
  • Substructure searching is too fast to recognize delay.
  • If function group or fingerprint is introduced as database index, the substructure searching could archive great performance on large scale dataset.
  • The data importing process is slow and the structure pictures generation process costs much more time and CPU. It took about half an hour to convert the 2700 BMP files on my thinkpad.

Other References


Appendix 1

Such Access DB can NOT serves for Asp.net or other applications connect through ODBC/DAO, for “ODBC and DAO do not use or know anything about the code modules inserted into an .mdb file by Access. Only Access recognizes the modules. ” announced by MSDN KB [Q166113] You cannot use user-defined modules through ODBC or DAO.

Access中的事件和委托

实际上对.Net中的“委托(delegate)”的概念并不很懂。如果仅理解成自定义事件的话,在Access中也可以部分实现。

窗体2中的自定义事件FireFromF2被窗体1捕获处理,参数被传递。用法很简单,注意WithEvents关键字的使用。

accessevent1.png
accesseventf1.png

accesseventf21.png

上面的例子要求先f2开启状态下再打开f1才能成功注册事件(原因见最后的总结)。如果是子窗体的事件,就简单一些,应用更常见。

accesseventf31.png

总结

  • WithEvents设置了事件监听的钩子,这个钩子针对的是Object,是实例,而不是Class或类型。
  • 所以可以监听Application这样的全局物件,也可以监听某个具体的Form。但是不能对所有的Form(Access.Form类型)起作用。
  • VBA中不支持自动的up-casting;WithEvents也不支持对象数组。所以后期绑定的方法也基本行不通。

Access (Jet SQL)中的function

MS Access是一种桌面型数据库引擎,基于Microsoft Jet database engine。一般用在很轻量级的应用上,以“方便”著称。其实某些方面也很强大,因为Jet SQL是有VBA集成在里面的。在写一些SQL作为query的时候,曾经因为发现Jet SQL内置的函数很少,而写了很多Dirty code。起码来说,没看到任何可用于非线性的计算函数(比如计算个人所得税时需要用到)。和T-SQL比较起来差的很远。直到最近发现可以使用VBA在SQL中,才发现这些问题不但可以解决,而且更容易了。

The Microsoft Jet database engine uses the Microsoft® Visual Basic® for Applications (or VBA) expression service to perform simple arithmetic and function evaluation. All of the operators used in Microsoft Jet SQL expressions (except Between, In, and Like) are defined by the VBA expression service. In addition, the VBA expression service offers over 100 VBA functions that you can use in SQL expressions.

SQL中的Function可以这样分为两种:Calculating fields和 SQL aggregate。自定义的聚集函数在SQL Server 2000里面也不支持,要到SQL Server 2005中才有。Calculating fields却可以利用VBA做出很多的扩展。

工具太容易上手,反而会使用户认识不到它全面的功能。微软的Office就是一个例子。

北京个人所得税计算的JET SQL Query:

SELECT
SalaryRMB,
IIF(SalaryRMB>1600,
    (SalaryRMB-1600)*
       IIF(SalaryRMB>=21600,0.25,
         IIF(SalaryRMB>=6600,0.20,
           IIF(SalaryRMB>=3600,0.15,
             IIF(SalaryRMB>=2100,0.10,0.05)  ) ))
      -IIF(SalaryRMB>=21600,1375,
         IIF(SalaryRMB>=6600,375,
           IIF(SalaryRMB>=3600,125,
             IIF(SalaryRMB>=2100,25, 0) ))),
0) AS SalaryTaxRMB
FROM tb_Salary

Random posts

  • 应对清华图书馆电子资源校外访问系统的BUG的办法
  • 晨雾回龙观
  • 中奖了,PS2
  • 母亲节,城墙下的笑容
  • Mind Map of ITIL v3