2014/12/10

Office 2013 クイック実行 Office 展開 - 8

Office 365 Advent Calendar 2014 に参加しています。10日目のポストです。

やっておかないとと思いつつ放置していた内容なのですが、いい機会なのでまとめ的にポストしています。クイック実行 / Click-to-Run の Office をできるだけ負担を少なく展開し更新の運用をしてみようという内容です。早速ですが 2014年分のデータ です。


Office 2013 は 2014/2 にSP1がリリースされていますので、相当するリリース(15.0.4569.1507)をインストールした状態から順次更新をしていった場合のダウンロード量を測ってみました。集計にはIISのログを使用しています。新規にインストールしようとするとき、更新を適用しようとするときにそれぞれダウンロードが必要になり、相応の流量を見積もっておく必要があるという傾向みたいなものです。この程度まったく平気だという環境ならばよいのですが。。。

2014/12/04

Office 365 Access アプリ -52- Download in Excel

Access アプリ の新機能
データシート ビュー から Excel ファイル(xlsx) のダウンロードができるようになった。
すでに配置された Access アプリ も順次アップグレードされていくはず。
Introducing a new feature in Access 2013 web apps—Download in Excel
しばらく前に情報は公開されていたのだけど、手元の環境で使用できるなったのでさらっと確認。小難しい内容は全くなく、コマンドボタンが自動的に配備されるから特段の手順などなく使えるようになる。特徴は 生成された Excel ファイルをダウンロードするということと、ダウンロードするとき最新のレコードを出力するから ビュー に表示されている レコード と異なる場合があること。


2014/08/24

Access 2013 ODBC リンク テーブル と SQL Server - 12

RecordsetOptionEnum 列挙 (DAO) dbSeeChanges
編集中のデータを別のユーザーが変更している場合、実行時エラーを生成します (ダイナセット タイプのみ)。
レコードが更新されていないことを確認して更新をする仕組み(オプティミスティック同時実行制御)になっている。この時発生する可能性がある実行時エラー は、
3197 :
The Microsoft Access database engine stopped the process because you and another user are attempting to change the same data at the same time.
他のユーザーが同じデータに対して同時に変更を試みているので、プロセスが停止しました。
なのだけど、
You must use the dbSeeChanges option with OpenRecordset when accessing a SQL Server table that has an IDENTITY column.
 IDENTITY 列を持つ SQL Server テーブルにアクセスする場合は、OpenRecordset で dbSeeChanges オプションを使用する必要があります。
なので、 dbSeeChanges を使用する必要がある。
そして、更新可能な レコードセットはその都度レコードを取得するので、何も考えずに使用すると遅い!とか言われることになる。そんな話。

2014/08/12

Access 2013 ODBC リンク テーブル と SQL Server - 11

さて、Recordset オブジェクト (DAO) です。Database.OpenRecordset メソッド (DAO)で Recordset を取得する。まずは、テーブル定義。都合がよいときもあるので rowversion (Transact-SQL)を持たせている。
CREATE TABLE Table_0(
  ID     int IDENTITY(1,1)
 ,F_Num  int
 ,F_Date date
 ,F_TS   rowversion
 CONSTRAINT PK_Table_0 PRIMARY KEY CLUSTERED (ID ASC)
)
この時、こんな感じでRecordsetを取り扱う。
Sub DAORecordset_Dynaset()
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset( _
                "SELECT ID, F_Num FROM Table_0" _
              , DAO.RecordsetTypeEnum.dbOpenDynaset _
              , DAO.RecordsetOptionEnum.dbSeeChanges _
              )
End Sub
レコードの更新/削除が可能。また、フィールドに主キーが含まれているから、レコードの追加が可能。なければ追加できない。OpenRecordset メソッドが実行された時、
SQLExecDirect: SELECT "dbo"."Table_0"."ID" FROM "dbo"."Table_0" 
SQLPrepare: SELECT "ID","F_Num","F_TS"  FROM "dbo"."Table_0"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLExecute: (GOTO BOOKMARK)
最初に主キーのみ取得する。条件があれば条件に該当する主キーのみ取得。その主キーを利用してレコードを取得する。該当するレコードがあれば先頭のレコードのみ取得まで。該当する他のレコードをすぐさま取得しないことと rowversion のフィールドを自動的に取得することがポイント。

2014/07/26

Access 2013 ODBC リンク テーブル と SQL Server - 10

ログばっかりで飽きてきたので、SQL Server 2014 Express LocalDB も使ってみる。SQL Server をさくっと試せるからいい感じ。
必要なもの:
Microsoft® SQL Server® 2014 Express
本体:SqlLocalDB.msi と、お好みで  管理用ツールは、SSMS
SSMS まで必要ないなら、PowerShell で管理できるように、
Microsoft® SQL Server® 2014 Feature Pack
  • SharedManagementObjects.msi
  • PowerShellTools.msi
インストールしたら、データベースとテーブルを作成。
Import-Module SQLPS -DisableNameChecking

# Create database
$QueryString = @"
    USE master;
    GO
    CREATE DATABASE testDB on (
        name =   'testDB1',
        filename='C:\LocalDB_data\testDB.mdf'
    )
    COLLATE Japanese_XJIS_100_CI_AS_KS_WS;
"@

Invoke-Sqlcmd $QueryString -ServerInstance '(LocalDB)\MSSQLLocalDB'


# Create table
$QueryString = @"
    USE testDB;
    GO
    CREATE TABLE Table_1 (
        ID int IDENTITY(1,1) NOT NULL
       ,F_Num int
       ,F_Date date
       ,CONSTRAINT PK_Table_1 PRIMARY KEY (ID ASC)
    )
"@

Invoke-Sqlcmd $QueryString -ServerInstance '(LocalDB)\MSSQLLocalDB'

# Drop database
Invoke-Sqlcmd "DROP DATABASE testdb" -ServerInstance "(localdb)\MSSQLLocalDB"
照合順序を Japanese_XJIS_100_CI_AS_KS_WS にしているのは、Access アプリに合わせているから。
"MSSQLLocalDB"は自動インスタンス名。試すぐらいならこのままでも困ることはない。
コマンド ライン管理ツール: SqlLocalDB.exe

2014/07/16

Access 2013 ODBC リンク テーブル と SQL Server - 9

Database.Execute メソッド を実行したとき。
Execute メソッド の Query パラメータは Access SQL で記述。そして、実際には、T-SQLに翻訳されてSQL Server で実行される。ACE は その操作に関与しているから、Database.RecordsAffected プロパティ で影響を受けたレコード数の取得は可能。
Sub test_Database_Execute()
On Error GoTo ErrHnd
    Dim dbs As DAO.Database
    Set dbs = CurrentDb
    
    dbs.Execute _
        "insert into Table_0 (F_Num) values (100);", _
        DAO.dbFailOnError
    Debug.Print dbs.RecordsAffected
    Debug.Print dbs.OpenRecordset("SELECT @@IDENTITY")(0)

    dbs.Execute _
        "update Table_0 set F_Num = 99 where F_Num = 100;", _
        DAO.dbFailOnError
    Debug.Print dbs.RecordsAffected

    dbs.Execute _
        "delete from Table_0 where F_Num = 99;", _
        DAO.dbFailOnError + DAO.dbSeeChanges
    Debug.Print dbs.RecordsAffected

Done:

Exit Sub
ErrHnd:
    If DBEngine.Errors.Count > 0 Then
        Dim e As DAO.Error, msg As String
        For Each e In DBEngine.Errors
            msg = msg & e.Number & ":" & e.Description & vbCrLf
        Next
        Debug.Print msg
    End If

    Resume Done
End Sub

2014/07/05

Access 2013 ODBC リンク テーブル と SQL Server - 8

CRUD の 残りひとつ、レコード を削除するときどのようになるのか。レコードの更新と概ね同じなのだけど。
DELETE Table_1.F_Num
FROM Table_1
WHERE Table_1.F_Num Between 15 And 20;
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" WHERE ("F_Num" BETWEEN 15 AND 20 ) 
SQLPrepare: SELECT "ID","F_Num","F_Date","F_Text","F_TS"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: DELETE FROM "dbo"."Table_1" WHERE "ID" = ?
SQLExecDirect: DELETE FROM "dbo"."Table_1" WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: DELETE FROM "dbo"."Table_1" WHERE "ID" = ?
SQLExecDirect: DELETE FROM "dbo"."Table_1" WHERE "ID" = ?
条件にマッチするレコードの主キーのみをまず取得。ここでレコード数が0であれば終了。そのあと、1レコードずつフェッチしながら削除を繰り返す流れ。

Access 2013 ODBC リンク テーブル と SQL Server - 7

レコードを更新してみる。わかってしまえば難しいことではないけど、Access らしい動作かなと。
UPDATE Table_1 SET Table_1.F_Num = 999, Table_1.F_Text = "ABC"
WHERE Table_1.ID In (10,11);
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" WHERE ("ID" IN (10 ,11 ) ) 
SQLPrepare: SELECT "ID","F_Num","F_Text"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: UPDATE "dbo"."Table_1" SET "F_Num"=?,"F_Text"=? WHERE "ID" = ?
SQLExecute: (UPDATE)
SQLExecute: (GOTO BOOKMARK)
SQLExecute: (UPDATE)
ここで実施されているのは、
1行目:抽出条件にマッチするレコードの主キーの取得
2行目:主キーをパラメータとするクエリの準備
3行目:準備されたクエリで1レコードフェッチ
4行目:更新用 SQLの準備
5行目:更新
6行目:準備されたクエリで1レコードフェッチ
7行目:更新
2行目の前にトランザクション開始、対象の更新完了後トランザクションcommit or rollback

2014/07/01

Access 2013 ODBC リンク テーブル と SQL Server - 6

レコードを追加するとき、ODBC データソースであるSQL Serverとの間でどのような処理がされるのか。
INSERT INTO Table_1 ( F_Text )
VALUES ('ABC');
SQLExecDirect: INSERT INTO  "dbo"."Table_1"  ("F_Text") VALUES (?)
SQLExecDirect: SELECT @@IDENTITY
ログ上ではこの内容のみとなるけど、実際には、
  1. トランザクション:begin
  2. exec sp_executesql N'INSERT INTO "dbo"."Table_1" ("F_Text") VALUES (@P1)',N'@P1 nvarchar(10)',N'XXX'
  3. SELECT @@IDENTITY
  4. トランザクション:commit or rollback
この動作は、追加 クエリだけに限らず、テーブルを開いてレコードを追加するときなどでも同じになる。

2014/06/28

Access 2013 ODBC リンク テーブル と SQL Server - 5

集計クエリについても見ておく。Where条件を持つ選択クエリと概ね同じ。少しだけ気を付けておけば、SQL Server側で集計が実施されるはず。
SELECT Table_1.F_Text, Sum(Table_1.F_Num) AS SumOfF_Num
FROM Table_1
GROUP BY Table_1.F_Text
HAVING Sum(Table_1.F_Num)>100;
SQLExecDirect: SELECT "F_Text" ,SUM("F_Num" )  FROM "dbo"."Table_1" GROUP BY "F_Text"  HAVING (SUM("F_Num" )  > 100 )
期待通りの集計がされて、全レコードを取得するようなことはない。ただし、

Access 2013 ODBC リンク テーブル と SQL Server - 4

演算 フィールドについて少し寄り道をして。
SELECT Table_1.ID, Table_1.F_Num, Year([F_Date]) AS F_Year, Month([F_Date]) AS F_Month
FROM Table_1;
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" 
SQLPrepare: SELECT "ID","F_Num","F_Date"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: SELECT "ID","F_Num","F_Date"  FROM "dbo"."Table_1"  WHERE "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ?
SQLExecute: (MULTI-ROW FETCH)
SQLExecDirect: SELECT "ID" ,"F_Num" ,"F_Date"  FROM "dbo"."Table_1"
演算は ACE もしくは Access で実施となる。

2014/06/25

Access 2013 ODBC リンク テーブル と SQL Server - 3

クエリ を開いたときどうなるの?。ベース テーブル が ODBC リンク テーブルという Access クエリで。
SELECT Table_1.ID, Table_1.F_Num
FROM Table_1;
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" 
SQLPrepare: SELECT "ID","F_Num"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: SELECT "ID","F_Num"  FROM "dbo"."Table_1"  WHERE "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ?
SQLExecute: (MULTI-ROW FETCH)
SQLExecDirect: SELECT "ID" ,"F_Num"  FROM "dbo"."Table_1" 
並び替え/抽出がないので、特に見どころはない。Dynaset の場合、主キーの取得がまず実施される。それらを利用しレコードをフェッチしていくことになる。Snapshot の場合、すべてのレコードを取得する。

2014/06/24

Access 2013 ODBC リンク テーブル と SQL Server - 2

作成した ODBC リンク テーブルを開いてみる。その時どのようなことが起きているか。
確認できるログは以下の通り。
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" 
SQLPrepare: SELECT "ID","F_Num"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: SELECT "ID","F_Num"  FROM "dbo"."Table_1"  WHERE "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ? OR "ID" = ?
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
SQLExecute: (MULTI-ROW FETCH)
大事なのは、1行目と4行目以降。

2014/06/23

Access 2013 ODBC リンク テーブル と SQL Server - 1

勉強用に SQL Server 2014 を インストール したのに別のことを始めてしまう。
Access 2013 としているけど、Access 2007 / 2010 と変わらんでしょう。違いがありそうなときは別途考える。
Access 2013 でSQL Server などODBC ソースに接続できる リンク テーブルの作り方については、
SQL Server のデータにリンクする
にあるから特に説明はない。DSN-less とかの工夫するくらいだろうか。
ともあれ、SQL Server にテーブルを作成して、ODBC リンク テーブルを。

2014/05/15

Office 2013 クイック実行 Office 展開 - 7

かいつまむと、クイック実行 / Click-to-Run の Office 2013 および Office 365 ProPlus の展開において Office 製品のインストールをそれぞれカスタマイズできるというお話。
更新されたツールと Build : 15.0.4615.1001 (2014/05/13公開分)以降のOffice が対象となる。

2014/05/12

Office 365 Access アプリ -51- Access 用コンテンツ アプリ - 5

どこに保管されるのだろうと思って。
Access アプリ を終了してから再度起動しても同じ情報を取得できるのだからきっとデータベース上にあるんだろうと思って確かめてみただけ。
SELECT [ID]
      ,[ObjectName]
      ,[Definition]
  FROM [AccessSystem].[Objects]
 WHERE [ObjectTypeNumber] = 112
ここでした。

2014/05/07

Office 365 Access アプリ -50- Access 用コンテンツ アプリ - 4

Binding.getDataAsync メソッド / Binding.getDataAsync method  options  パラメータのうち、filterType / rows について確認してみた。
FilterType 列挙体 / FilterType enumeration / "thisRow"
配置はこの状態

2014/05/03

Office 365 Access アプリ -49- Access 用コンテンツ アプリ - 3

SPC 2014 で公開されていた "Access 用コンテンツ アプリ / Contents apps for Access" の Bing Maps サンプル が更新されていたので。


2014/05/01

Office 365 Access アプリ -48- Access 用コンテンツ アプリ - 2

"Access アプリ / Access app" だけだど表現が乏しいから、"Access 用コンテンツ アプリ / Contents apps for Access" を使ってグラフの表示をやってみた。
スクラッチで実装するのは避けて Chart.js を使ってみることにした。Canvas を使用するけど、
Office 365 と Internet Explorer に関する FAQ
にある通り対応については問題なかろうかと。
で、出来上がり。


2014/04/23

2014/04/20

Office 365 Access アプリ -47- Access 用コンテンツ アプリ - 1

一応やっておかないとかなと。MSDN ライブラリだけ読んでやってみる。
とりあえず、このような構成。
そしてこんな感じになる。
"レコード移動時 / OnCurrent" や "レコード更新時 / AfterUpdate"などイベントでフィールドの値が取れたりすればいいかなと。

2014/04/03

Windows 8.1 Update をインストールした

MSDNで先行して公開されたWindows 8.1 Update を新規インストールしてみた。スタート画面とか私にはどうでもいいのだ。

インストール後、Windows Updateでどれくらい適用が必要なのか見てみた。だいぶ適用済みなのかな。すっきりしてていいかなと。

2014/03/16

Office 365 Access アプリ -46- Office 用アプリ を作ってみる

Visual Studio 2013 のアップデートもしてなかったので、一緒に試してみようという時のメモ。

まずはプロジェクトの作成

2014/03/15

Office 365 Access アプリ -45- SPC2014

先日開催された SharePoint Conference 2014(SPC2014)のセッションのうち、Access Services に関するものを拾って列挙。

Anyone can build a SharePoint App with Microsoft Access
以前のイベントであった内容とおおむね同じ。Access アプリ / Access app は開発者が作らなければならないものでなく、エンドユーザが自分で使うものを作れるということが要点のうちのひとつ。


2014/03/09

SharePoint2013 Access Services -11-

Service Pack 1 がちょっと前に出たので、Windows Server 2012 R2 にインストールしてみた。Access Service だけが動作すればよいのでインストール手順は変わりなく。
久しぶりなので、かなり手順を忘れてた。よーく読んでれば何とかなる。

2014/02/26

Office 365 Access アプリ -44- Office用 アプリ

Access も Apps for Office に対応となるというお話。まだ、詳細な情報はないけれども。

ちょっと強引なところから追加するような感じになっているのだけど、Access アプリ のビュー上に挿入するという感じになるはずです。ビューに紐づけられたレコードセットを Office用 アプリで参照などしてお好きなように表示(特にグラフィカル)などするという感じになろうかと。

Office 2013 Service Pack 1 リリース

SPC 2014 があるからそれくらいまでには出るんだろうなと思ってたら、割と直前だった。
Description of Microsoft Office 2013 Service Pack 1 (SP1)
でかーい

2014/02/16

Office 365 Access アプリ -43- イメージフィールド

仕様が変わったというか、今までプレビューだったからと言ってしまえばそれまでなのだけど。


デザイン時や単純に Access アプリ を使っている分には特に対応する必要はないけれども、イメージデータの格納が内部的に分割されているので Access アプリ のデータを別のアプリケーションで使用したいとするときイメージデータについては多少の工夫は必要になる。

2014/02/13

Office 365 ユーザー向けに Access アプリの一般提供を開始

ぇ?そうだったの。。。
Office 365 ユーザー向けに Access アプリの一般提供を開始
Access apps General Availability for Office 365 customers
記事は2/3に読んではいたのだけど、いったい何を言ってんだろと思っていたわけで。
SLA とかOffice 365 の保証基準が適用されるってこと。
 とりあえずスタートが切れたってことで、よかったね。

2014/02/06

Access 2013 マクロの文字数制限

久しぶりで投稿の手順を忘れている。アカウントを増やしたくなかったので自前のブログに書くのだけど。

Access 2013 / 2010 の マクロエディタ / Logic designer 上で値を設定しようとするとき、文字数の制限を受けることがある。
 MSアクセスマクロWhere条件式に256文字制限
UI のバリデーションで先に進めないのですが、文字数制限を突破することが可能な場合はある。