PHP Conference Japan 2024

COM 函數

另請參閱

如需更多關於 COM 的資訊,請閱讀» COM 規格。您可能會在我們的 PHP 和 COM FAQ 中找到一些額外的實用資訊。如果您正考慮在伺服器端使用 MS Office 應用程式,您應該閱讀這裡的資訊:» 關於 Office 伺服器端自動化的考量

目錄

新增筆記

使用者貢獻筆記 31 筆筆記

9
Sorin Negulescu
8 年前
我花了許多時間嘗試讓 word.application 在使用 Apache 作為服務的 Windows 伺服器上運作。
如果從命令列啟動 Apache (而不是作為服務),應用程式就可以運作。

希望這可以幫助其他人不要浪費時間嘗試解決這個問題,這是我發現的

- 在 php.ini 中,請確定在 [COM_DOT_NET] 下有以下索引鍵:extension=php_com_dotnet.dll
- Apache 應在一般使用者帳戶 (而不是 SYSTEM 帳戶) 下執行。執行 services.msc 並在 Apache 服務的 [屬性] 索引標籤下填入使用者的資訊。
- 請確定您可以使用該使用者帳戶正常啟動 MS Word,並關閉可能出現的所有對話方塊 (授權、您帶有縮寫的資訊等等)。再次啟動 Word,並確定沒有出現任何對話方塊。
- 啟動 dcomcnfg.exe->[主控台根目錄]->[元件服務]->[電腦]->[我的電腦]->[DCOM 設定]->[Microsoft Office Word 97 - 2003]->按一下滑鼠右鍵 ([屬性])->[身分識別] 索引標籤,然後填入與 Apache 服務相同的使用者帳戶資訊。
- 如果您找不到 Microsoft Office Word 97 - 2003,請確定您啟動的 DCOM 設定正確 (64 位元與 32 位元),這取決於您安裝的 Office 版本。若要啟動 32 位元版本,請執行:mmc comexp.msc /32

在遵循上述步驟之前,winword.exe 應用程式會出現在工作管理員中,但是如果您查看記憶體消耗量,您可以注意到兩件事
- 它會緩慢增加
- 它通常會在約 7-8 MB 時停止。

關鍵字:COM、word.application、Apache、服務、winword、逾時、無錯誤
3
tomas dot pacl at atlas dot cz
21 年前
在 PHP 4.3.2 (以及未來版本的 PHP ) 中,按參考傳遞參數

在 PHP 4.3.2 中,allow_call_time_pass_reference 選項預設設定為「關閉」,而且未來版本可能不再支援這個選項。
某些 COM 函數具有 by-reference 參數。VARIANT 物件必須用來呼叫這些函數,但是它會在沒有變數名稱之前的 '&' 的情況下傳遞。

範例

<?php
$myStringVariant
= new VARIANT("over-write me", VT_BSTR);

/* 正常運作 */
$result = $comobj->DoSomethingTo($myStringVariant );

/* 只有在 allow_call_time_pass_reference 選項設為 "On" 時才運作,且可能在 PHP 的未來版本中失效 */
$result = $comobj->DoSomethingTo(&$myStringVariant );

/* 變數中的值可以透過以下方式取得: */
$theActualValue = $myStringVariant->value;
?>
4
tomfmason at nospam-gmail dot com
17 年前
要取得 CPU 使用率百分比,您可以執行類似以下的操作。

<?php
$wmi
= new COM('winmgmts://');
$processor = $wmi->ExecQuery("SELECT * FROM Win32_Processor");
foreach(
$processor as $obj){
$cpu_load_time = $obj->LoadPercentage;
}
echo
$cpu_load_time;
?>

參考 http://msdn2.microsoft.com/en-us/library/aa394373.aspx

列出目前 Apache 執行個體

<?php
$wmi
= new COM('winmgmts://');
$processes = $wmi->ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'httpd.exe'");
foreach(
$processes as $process){
echo
$process->CommandLine . "<br />";
echo
$process->ProcessId . "<br />";
}
?>

參考 http://msdn2.microsoft.com/en-us/library/aa394372.aspx

在背景程序中執行 PHP 腳本

<?php
$dir
= "C:\\path\\to\\dir";
$php_path = "C:\\path\\to\\php.exe";
$file = "somescript.php";
//傳送時間目前時間戳記
$cmd_options = "-t " . time();
$wscript = new COM('WScript.Shell');
$wscript->Run("cmd /K CD $php_path $dir\\$file & ", 0, false);
?>

請享用

Tom
4
ferozzahid [at] usa [dot] com
20 年前
若要透過參考將參數傳遞給 COM 函式,您需要將 VARIANT 傳遞給它。常見的資料類型(例如整數和字串)無法用於此目的。

舉例來說,呼叫一個會擷取人員姓名的函式看起來會像這樣

<?php
$Name
= new VARIANT;

$comobj = new COM("MyCOMOBj.Component") or die("無法建立 COM 元件");

if(!
$comobj->GetName($Name)) {
echo(
"無法擷取名稱");
}
else {
echo(
"擷取的名稱是: " . $Name->value);
}
?>

$Name->type 將包含 VARIANT 中儲存的值的類型,例如 VT_BSTR。

PHP 5 注意事項

要取得 VARIANT 中儲存的值,我們可以只使用 '$Name',而不用 '$Name->value'。若要取得 VARIANT 中儲存的值的類型,請使用 'variant_get_type($Name)'。

Feroz Zahid
2
Francois-R dot Boyer at PolyMtl dot ca
17 年前
我嘗試從 PHP 呼叫 Access VBA 腳本時遇到問題;呼叫可以正常運作,但 Access 永遠不會結束。問題在於 Apache 伺服器是以 SYSTEM 身分執行,而不是我們通常用來執行 Office 的使用者。而且當使用者第一次執行 Office 時,它會要求 SYSTEM 使用者輸入其名稱和縮寫! ;-)

若要修正這個問題:停止 Apache,前往「服務」,找到 Apache,按一下「內容」,選擇「登入」索引標籤,然後勾選「允許服務與桌面互動」。重新啟動 Apache,然後透過 Apache 伺服器載入的頁面開啟您的 Office 應用程式,並使用像這樣的少量 PHP 程式碼,

<?php
$app
= new COM("Access.Application"); // 或 Word.Application 或 Excel.Application ...
$app->Visible = true; // 讓視窗顯示在螢幕上
?>

輸入您想要的名稱,然後結束應用程式。現在,您的 Office 應用程式在下次使用 PHP 中的 COM 物件載入時,應該就會正確終止。您可以停止 Apache,取消勾選「允許服務與桌面互動」,然後重新啟動 Apache(如果您願意)。我甚至不需要傳送 Quit 或任何東西給 Access,當 PHP 結束時,它就會自動結束。

對於那些想要知道我如何呼叫 Access VBA 腳本的人,我沒有使用 ODBC 或任何其他方式傳送 SQL 要求(似乎無法運作來呼叫 VBA 腳本),而是將資料庫以 COM 物件的形式開啟,這樣可以正常運作

<?php
$db_com
= new COM("檔案.mdb 的路徑名稱");
$result = $db_com->Application->Run("function_name", 'param1', 'param2', '...');
?>
1
naveed at php dot net
17 年前
這是一個拼字檢查實作,會針對每個拼錯的單字顯示建議清單。

<?php
function SpellCheck($input)
{
$word=new COM("word.application") or die("無法建立 Word 物件");
$word->Visible=false;
$word->WindowState=2;
$word->DisplayAlerts=false;
$doc=$word->Documents->Add();
$doc->Content=$input;
$doc->CheckSpelling();
$result= $doc->SpellingErrors->Count;
if(
$result!=0)
{
echo
"輸入的文字包含拼寫錯誤。\n\n";
for(
$i=1; $i <= $result; $i++)
{
echo
"原始單字: " .$doc->SpellingErrors[$i]->Text."\n";
$list=$doc->SpellingErrors[$i]->GetSpellingSuggestions();
echo
"建議: ";
for(
$j=1; $j <= $list->Count; $j++)
{
$correct=$list->Item($j);
echo
$correct->Name.",";
}
echo
"\n\n";
}
}
else
{
echo
"沒有發現拼寫錯誤。";
}
$word->ActiveDocument->Close(false);
$word->Quit();
$word->Release();
$word=null;
}

$str="Hellu world. There is a spellling error in this sentence.";
SpellCheck($str);
?>
1
alanraycom at el hogar dot net com
21 年前
使用 MSXML 的 XSLT 轉換可以使用此程式碼完成

<?php
function xsltransform1($xslpath,$xmlstring)
{
$xml= new COM("Microsoft.XMLDOM");
$xml->async=false;
// $xmlstring 是一個 xml 字串
$xml->load($xmlstring);
$xsl = new COM("Microsoft.XMLDOM");
$xsl->async=false;
// $xslpath 是 xsl 檔案的路徑
$xsl->load($xslpath);
$response=$xml->transformNode($xsl);
unset(
$xml);
unset(
$xsl);
return
$response;
}
?>

請享用
Alan Young
2
madon at cma-it dot com
22 年前
我認為這個 Excel 圖表範例可能很有用。

請注意 Excel.application 與 Excel.sheet 的用法。

<pre>
<?php
print "Hi";
# 實例化試算表元件。
# $ex = new COM("Excel.sheet") or Die ("連線失敗");
$exapp = new COM("Excel.application") or Die ("連線失敗");

# 取得應用程式名稱和版本
print "應用程式名稱:{$ex->Application->value}<BR>" ;
print
"載入版本: {$ex->Application->version}<BR>";

$wkb=$exapp->Workbooks->add();
#$wkb = $ex->Application->ActiveWorkbook or Die ("無法開啟活頁簿");
print "我們開啟了活頁簿<BR>";

$ex->Application->Visible = 1; #讓 Excel 可見。
print "我們讓 Excel 可見<BR>";

$sheets = $wkb->Worksheets(1); #選取工作表
print "已選取工作表<BR>";
$sheets->activate; #啟用工作表
print "已啟用工作表<BR>";

#這是一個新的工作表
$sheets2 = $wkb->Worksheets->add(); #新增工作表
print "已新增一個新工作表<BR>";
$sheets2->activate; #啟用它
print "已啟用工作表<BR>";

$sheets2->name="報表第二頁";

$sheets->name="報表第一頁";
print
"我們設定了工作表的名稱: $sheets->name<BR>";

# 填入欄位
$maxi=20;
for (
$i=1;$i<$maxi;$i++) {
$cell = $sheets->Cells($i,5) ; #選取儲存格 (列數, 欄數)
$cell->activate; #啟用儲存格
$cell->value = $i*$i; #將值變更為 15000
}

$ch = $sheets->chartobjects->add(50, 40, 400, 100); # 建立圖表物件

$chartje = $ch->chart; # 在圖表物件中放置圖表
$chartje->activate; #啟用圖表物件
$chartje->ChartType=63;
$selected = $sheets->range("E1:E$maxi"); # 設定圖表使用的資料
$chartje->setsourcedata($selected); # 設定圖表使用的資料
print "設定了圖表使用的資料 <BR>";

$file_name="D:/apache/Apache/htdocs/alm/tmp/final14.xls";
if (
file_exists($file_name)) {unlink($file_name);}
#$ex->Application->ActiveWorkbook->SaveAs($file_name); # 將工作表儲存為 final.xls
$wkb->SaveAs($file_name); # 將工作表儲存為 final.xls
print "已儲存<BR>";

#$ex->Application->ActiveWorkbook->Close("False");
$exapp->Quit();
unset(
$exapp);
?>

</pre>

Alex Madon
2
匿名
18 年前
如果有人想從 DCOM 物件中取得 COM 物件,可以這樣做

<?php
$dcom_obj
= new COM('dacom.object','remotehost') or die("無法取得 DCOM 物件!");
$com_obj = new Variant(NULL);
$dcom_obj->Get_Module($com_obj); //使用者函式,傳回自訂的 IDispatch (強制轉換為 variant*)
?>

希望這對某些人有所幫助,因為我花了很長時間才弄清楚這一點。
1
a dot kulikov at pool4tool dot com
18 年前
如果您想知道如何在新建立的 EXCEL 檔案中群組列或欄,那麼這可能會對您有所幫助

<?php
/***
* 在 Excel 中使用 COM 物件以視覺方式群組列
*
* 這並不容易,我花了幾個小時的試錯才讓這個東西運作!!!
*
* @author Kulikov Alexey <a.kulikov@gmail.com>
* @since 13.03.2006
*
* @see 開啟 Excel,按下 Alt+F11,然後按下 F2 -- 這是您的 COM 聖經
***/

//啟動 excel
$excel = new COM("excel.application") or die("無法實例化 excel");
print
"已載入 excel,版本 {$excel->Version}\n";

//將其帶到最前面
#$excel->Visible = 1;//不要

//不想要警示 ... 靜默執行
$excel->DisplayAlerts = 0;

//建立新的活頁簿
$wkb = $excel->Workbooks->Add();

//選取預設工作表
$sheet=$wkb->Worksheets(1);

//將其設為使用中工作表
$sheet->activate;

//用一些虛擬資料填入
for($row=1;$row<=7;$row++){
for (
$col=1;$col<=5;$col++){

$sheet->activate;
$cell=$sheet->Cells($row,$col);
$cell->Activate;
$cell->value = 'pool4tool 4eva ' . $row . ' ' . $col . ' ak';
}
//colcount for 迴圈結束
}

///////////
// 選取第 2 到 5 列
$r = $sheet->Range("2:5")->Rows;

// 將它們群組起來,寶貝,耶
$r->Cells->Group;

// 儲存新檔案
$strPath = 'tfile.xls';
if (
file_exists($strPath)) {unlink($strPath);}
$wkb->SaveAs($strPath);

//關閉活頁簿
$wkb->Close(false);
$excel->Workbooks->Close();

//釋放 RAM
unset($sheet);

//關閉 excel
$excel->Quit();

//釋放物件
$excel = null;
?>
1
Pedro Heliodoro
18 年前
我使用 Windows Media Player OCX 和最新的 PHP 5.1 快照,成功彈出了 CD-ROM 光碟機。

<?php
// 建立 Windows Media Player 的實例
$mp = new COM("WMPlayer.OCX");
// 彈出光碟機清單上的第一台光碟機
$mp->cdromcollection->item(0)->eject();

?>
2
angelo [at] mandato <dot> com
20 年前
我建立了一些實用的 PHP 函式(類似於其他標準的 PHP 資料庫函式),用於處理 ADO 資料來源。
<?php
// ado.inc.php

$ADO_NUM = 1;
$ADO_ASSOC = 2;
$ADO_BOTH = 3;

function
ado_connect( $dsn )
{
$link = new COM("ADODB.Connection");
$link->Open($dsn);
return
$link;
}

function
ado_close( $link )
{
$link->Close();
}

function
ado_num_fields( $rs )
{
return
$rs->Fields->Count;
}

function
ado_error($link)
{
return
$link->Errors[$link->Errors->Count-1]->Number;
}

function
ado_errormsg($link)
{
return
$link->Errors[$link->Errors->Count-1]->Description;
}

function
ado_fetch_array( $rs, $result_type, $row_number = -1 )
{
global
$ADO_NUM, $ADO_ASSOC, $ADO_BOTH;
if(
$row_number > -1 ) // 在 adoint.h 中定義 - adBookmarkFirst = 1
$rs->Move( $row_number, 1 );

if(
$rs->EOF )
return
false;

$ToReturn = array();
for(
$x = 0; $x < ado_num_fields($rs); $x++ )
{
if(
$result_type == $ADO_NUM || $result_type == $ADO_BOTH )
$ToReturn[ $x ] = $rs->Fields[$x]->Value;
if(
$result_type == $ADO_ASSOC || $result_type == $ADO_BOTH )
$ToReturn[ $rs->Fields[$x]->Name ] = $rs->Fields[$x]->Value;
}
$rs->MoveNext();
return
$ToReturn;
}

function
ado_num_rows( $rs )
{
return
$rs->RecordCount;
}

function
ado_free_result( $rs )
{
$rs->Close();
}

function
ado_query( $link, $query )
{
return
$link->Execute($query);
}

function
ado_fetch_assoc( $rs, $row_number = -1 )
{
global
$ADO_ASSOC;
return
ado_fetch_array( $rs, $ADO_ASSOC, $row_number);
}

function
ado_fetch_row( $rs, $row_number = -1 )
{
global
$ADO_NUM;
return
ado_fetch_array( $rs, $ADO_NUM, $row_number);
}

// 額外函式:
function ado_field_len( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Precision;
}

function
ado_field_name( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Name;
}

function
ado_field_scale( $rs, $field_number )
{
return
$rs->Fields[$field_number]->NumericScale;
}

function
ado_field_type( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Type;
}

?>

aod 版本是個錯字。
1
monica at digitaldesignservices dot com
16 年前
使用 Word 2003 COM 物件。

您是否嘗試使用 Word.Application COM,但 Word 文件會當機,而 PHP 腳本會停滯?

事實證明,Office COM 物件中存在一個問題,它不允許 Web 應用程式(IIS、Apache)的腳本引擎在實例化 COM 後釋放該物件。Office Service Pack 3 更新宣稱可以解決這個問題。我將測試並發布結果。
1
allan666 at gmail dot com
19 年前
如果您正在使用會開啟視窗或對話方塊(例如 Office 應用程式)的 COM 物件,這些視窗或對話方塊將不會出現,即使您使用類似以下的程式碼,它們仍會保持隱形狀態:

$word->visible = true;

要解決這個問題,請前往 Web 服務的屬性(管理工具),然後點擊「登入」索引標籤中的「允許服務與桌面互動」。

這解釋了關閉應用程式時的許多問題。當您嘗試關閉時,要求儲存檔案的對話方塊必須出現,但只有在開啟與桌面互動的選項時才會出現。

希望這對您有幫助。
1
bruce at yourweb dot com dot au
19 年前
簡單地將 xls 轉換為 csv。
<?php
// 啟動 Excel
$excel = new COM("excel.application") or die("無法啟動 Excel");
print
"已載入 Excel,版本 {$excel->Version}\n";

// 將其顯示在最前端
#$excel->Visible = 1;// 不要這樣做
// 不要出現警告訊息... 靜默執行
$excel->DisplayAlerts = 0;

// 開啟檔案
$excel->Workbooks->Open("C:\\mydir\\myfile.xls");
// XlFileFormat.xlcsv 檔案格式為 6
// 另存新檔指令 (檔案, 格式 ......)
$excel->Workbooks[1]->SaveAs("c:\\mydir\\myfile.csv",6);

// 關閉 Excel
$excel->Quit();

// 釋放物件
$excel->Release();
$excel = null;
?>
1
michael at example dot com
19 年前
在 IIS 6/Windows 2003 和 PHP 5.0.2 上遇到許多問題後,我終於弄清楚如何使用 Imagemagick COM+/OLE 介面。似乎每次使用 convert() 後都必須重新建立 COM 物件,否則有時候會出現非常奇怪的錯誤,因為 PHP COM 介面顯然不如舊的 ASP 介面穩定。
1
Anonymous
19 年前
如果你想在 Excel 中新增超連結

<?php
$cell
=$sheet->Range('O'.$j);
$cell->Hyperlinks->Add($cell ,'here_your_file');
?>

我寫下這個筆記是因為這很難找到
實現這個目標的正確方法。

Merci beaucoup
1
Shawn Coppock
20 年前
對於我們這些不熟悉物件模型的人來說,如果你有 Microsoft Excel 或 Microsoft Word,請進入 Visual Basic 編輯器 (Alt+F11)。現在你可以開啟物件瀏覽器視窗 (F2) 並看看你能找到什麼。

如果你在物件瀏覽器中選擇「Word」,則該類別的類別和成員會顯示在下方。例如,如果你在類別欄中點擊「Selection」,然後在成員欄中點擊「Font」,你就會在底部看到「Property Font As Font Member of Word.Selection」。點擊那裡的「Font」連結。

再次在類別欄中點擊 Word「Selection」,然後在成員欄中點擊「PageSetup」,你就會在底部看到「Property PageSetup As PageSetup Member of word.Selection」。點擊那裡的「PageSetup」連結。

使用以上範例,你現在可以從 PHP 建立你的 Word 文件。這是一個簡單的範例,它根據邊界設定建立 1 & 1/2 英吋的文字空間,並使用深紅色的文字和 8pt Helvetica 字體。

<?php
$content
= "在此插入範例文字\n\n這開始一個新的段落行。";
$word= new COM("word.application") or die("無法建立 Word 文件");
print
"已載入 Word,版本 {$word->Version}\n";
$word->Visible = 0;
$word->Documents->Add();
$word->Selection->PageSetup->LeftMargin = '3"';
$word->Selection->PageSetup->RightMargin = '4"';
$word->Selection->Font->Name = 'Helvetica';
$word->Selection->Font->Size = 8;
$word->Selection->Font->ColorIndex= 13; //wdDarkRed = 13
$word->Selection->TypeText("$content");
$word->Documents[1]->SaveAs("some_tst.doc");
$word->quit();
echo
"完成";
?>

這個範例(和其他範例)在 Microsoft Word 10.0 物件庫 (MS Word 2002)、Apache 和 Windows XP 上的 PHP 中對我有效。使用 Visual Basic 編輯器進行實驗將會從 PHP 產生一些驚人的文件,因為它可以幫助你了解所使用物件之間的關係,並讓你了解如何建構你的程式碼。但如果你的程式碼嚴重偏離,請準備好 PHP.exe 崩潰的情況。

希望這對您有所幫助!
1
mark dickens at mindspring dot com
20 年前
對於那些想要在 Windows 2000/XP 下使用 COM 與印表機介面的人,請注意。如果它無法運作或似乎掛起,請嘗試將執行 Apache(假設你正在使用 Apache)服務的登入身分從系統帳戶更改為另一個帳戶。預設情況下,大多數服務將安裝為在系統帳戶下執行,雖然系統帳戶對其執行的電腦具有完全權限,但據我所知,它在該領域之外沒有任何權限。顯然,存取印表機被認為是「超出領域」。我使用此技術將 Dymo 熱感應標籤印表機連接到我的伺服器,現在它可以運作了。
1
chris at hitcatcher dot com
21 年前
當傳遞長 (win32) 檔名作為函式參數時,許多 COM 物件都無法正常運作。 你可以使用以下方法取得 *大多數* (某些 Windows 平台不支援,並且可以出於效能原因在登錄檔中切換關閉) 伺服器上資料夾或檔案的 8.3 名稱

<?php
// 建立 FSO 實例
$exFSO = new COM("Scripting.FileSystemObject") or die ("無法建立 Scripting.FileSystemObject");

// 設定變數
$myDir = "C:\\Program Files\\";
$myFile = "一個很長的文件名稱.txt";

// 取得資料夾和檔案物件
$exDir = $exFSO->GetFolder($myDir);
$exFile = $exFSO->GetFile($myDir . $myFile);
echo
$exDir->ShortPath;
echo
$exFile->ShortPath;
?>
1
Anonymous
21 年前
這是一個讀取自訂屬性的範例,例如作者、關鍵字等,這些屬性儲存在 MS Office 和其他 Windows 檔案中。 您必須安裝並註冊 dsofile,如 http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q224351. 中所述。 該發行版中的 .frm 檔案列出了大多數可用的屬性。

<?php
// 你想要存取的檔案
$fn = '/docs/MFA.xls';

$oFilePropReader = new COM('DSOleFile.PropertyReader');
$props = $oFilePropReader->GetDocumentProperties($fn);

// 一種語法
$au = com_get($props, 'Author');
print
"au: $au \n";

// 另一種語法
$str = 'LastEditedBy';
$lsb = $props->$str;
var_dump($lsb);

// 如果你想要設定屬性
if (!$props->IsReadOnly()) {
$props->Subject = 'tlc';
}
?>
1
php at dictim dot com
21 年前
我花了幾天才搞清楚如何做到,所以必須分享一下

如何從 MS Word 文件取得字數

<?php
# 實例化 Word 元件。

$word = new COM("word.application") or die("無法實例化 Word");

$word->Visible = 1;

$word->Documents->Open("c:/anydocument.doc");
$temp = $word->Dialogs->Item(228);
$temp->Execute();
$numwords = $temp->Words();

echo
$numwords;

$word->Quit();
?>

請注意,這是唯一能準確取得字數的方法
$word->ActiveDocument->Words->Count;
會將所有歸位字元和標點符號視為單字,因此非常不準確。
1
tedknightusa at hotmail dot com
22 年前
一個 Notes 範例

<?php
$session
= new COM "Lotus.NotesSession" );
$session->Initialize($password);

$someDB = "C:\Lotus\Notes\Data\somedb.nsf";
$db = $session->GetDatabase("", $someDB) or die("無法取得 someDB.nsf");
$view = $db->GetView("some_view") or die("找不到 Some View");

$doc = $view->GetFirstDocument() or die("無法取得初始 Some Document");

// 迴圈遍歷
while($doc){
$col_vals = $doc->ColumnValues();
echo
$col_vals[0];
$doc = $view->GetNextDocument($doc);
}
?>
1
dwt at myrealbox dot com
22 年前
當我第一次編寫實例化 COM 物件的應用程式時,總是面臨實例化的程式無法正確終止的問題,儘管其他所有功能都正常運作。事實上,必須使用工作管理員手動終止該程序。在經過一些實驗後,我能夠找出這種特殊行為的原因,以下面的範例程式碼來說明。

<?php

//透過函式 ArrayName(Index) 檢索元素來存取陣列是可行的,但肯定既沒有效率也不是良好的風格
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);

$sheet->Name="Debug-Test";
$book->saveas("C:\\debug.xls");

$book->Close(false);
unset(
$sheet);
unset(
$book);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

//像平常一樣存取陣列(使用 [] 運算子)是可行的,但會導致應用程式無法自行終止
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$excel->Workbooks[1]->Worksheets[1]->Name="Debug-Test";
$excel->Workbooks[1]->saveas("C:\\debug.xls");

$excel->Workbooks[1]->Close(false);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

?>

範例程式碼執行相同的動作兩次,每次都會正確建立檔案。然而,由於某些神秘的原因,一旦你以大多數程式設計師(尤其是那些在 c++ 中進行大量 oop 的程式設計師)的方式存取陣列,實例化的 excel 程式就不會終止!因此,在 PHP 開發人員意識到這個問題之前,我們必須使用第一個範例中說明的低效率編碼風格。
0
larrywalker at at chelseagroton dot com
16 年前
若要在背景處理程序中執行 php 腳本並傳遞您的變數,請使用

<?php

$WshShell
= new COM("WScript.Shell");
$oExec = $WshShell->Run("c:\\xampp\\php\\php.exe

c:\\xampp\\Not_on_Web\\ftptestback.php --user=
$username", 7, false);

?>

對我來說可以運作。
0
kiotech at hotmail dot com
18 年前
若要在 PHP 中使用參數,這是一個程式碼範例

<?php
$ObjectFactory
= New COM("CrystalReports11.ObjectFactory.1");
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application");
$creport = $crapp->OpenReport("//report1.rpt", 1);


$z= $creport->ParameterFields(1)->SetCurrentValue("Mango");
$z= $creport->ParameterFields(2)->SetCurrentValue(5000);

$creport->ExportOptions->DiskFileName="reportin.pdf";
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; $creport->ExportOptions->FormatType=31;
$creport->Export(false);

$len = filesize("reportin.pdf");
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=reportin.pdf");
readfile("reportin.pdf");
?>
0
sorin dot andrei at mymail dot ro
20 年前
[編輯註記
將物件序列化、儲存,然後(在下一頁)還原序列化將會有效。]
結束註記]

PHP 的大問題是它無法將 COM 物件儲存在 session 中

範例程式碼如下。這只在第一次執行時有效,之後會出現錯誤
在 $mMap->Refresh(); 這行呼叫了未定義的方法 com::Refresh()
原因是它無法將物件 $mMap 儲存在 session 中

<?php
session_start
();
if (isset(
$_SESSION['map'])) {
$mMap = $_SESSION['map'];
}
else
{
$ArcIMSConnector = new COM ("aims.ArcIMSConnector") or die("無法建立 AIMS 訊息物件");
echo
"已載入 ArcIMSConnector, <br>";
$ArcIMSConnector->ServerName = "map.sdsu.edu";
$ArcIMSConnector->ServerPort = 5300;

$mMap = new COM ("aims.Map") or die("無法建立 aims.Map 訊息物件");
echo
"已載入 aims.Map, <br>";
print
"AIMS-ServerName= $ArcIMSConnector->ServerName <br>";

$resultInit= $mMap->InitMap($ArcIMSConnector,"Worldgeography");

$mMap->Width = 400; // '地圖寬度,以像素為單位
$mMap->Height = 300; // '地圖高度,以像素為單位
$mMap->BackColor = 15130848;
$_SESSION['map'] = $mMap;
}

$resultRefresh = $mMap->Refresh(); //重新整理地圖
$urlImage = $mMap->GetImageAsUrl();
print
"<br>urlImage=$urlImage<br>";

print
"<br><IMG SRC='$urlImage'>";

/*
$ArcIMSConnector->Release();
$ArcIMSConnector = null;

$mMap->Release();
$mMap = null;
*/

?>
0
brana
21 年前
如何透過 MAPI 發送電子郵件(適用於 Windows NT4,apache 以服務方式啟動)

<?php
#建立新的 MAPI 工作階段...
$session = new COM("MAPI.Session");

#登入
$strProfileInfo = "exchange_server" . chr(10) . "exchange_user";
$session->Logon("", "", 0, 1, 0, 1, $strProfileInfo);

# 新訊息...
$msg = $session->Outbox->Messages->Add();
$msg->Subject = "主旨";
$msg->Text = "內文";

#設定收件者...
$rcpts = $msg->Recipients;
$rcpts->AddMultiple("toto@toto.com", 1); #收件者...
$rcpts->AddMultiple("titi@titi.com", 2); #副本...
$rcpts->AddMultiple("tutu@tutu.com", 3); #密件副本...

# 解析寄件者
$rcpts->Resolve();

#發送訊息
$msg->Send();

#登出
$session->Logoff();

#清除
if($msg!=null) {
$msg->Release();
$msg = null;
}
if(
$session!=null) {
$session->Release();
$session = null;
}
?>

ps:啟動服務的 NT 帳戶和 Exchange 使用者必須匹配!
0
richard dot quadling at carval dot co dot uk
21 年前
感謝 Harald Radi 和 Wez Furlong。

某些 VBA 函數有選擇性參數。有時您想要傳遞的參數不是連續的。

例如:

GoTo What:=wdGoToBookmark, Name="BookMarkName"
GoTo(wdGoToBookmark,,,"BookMarkName)

在 PHP 中,「空白」參數必須為空。

也就是...

<?php
// 某些伺服器可能有自動逾時設定,所以讓程式執行久一點。
set_time_limit(0);

// 在開發期間顯示所有錯誤、警告和提示。
error_reporting(E_ALL);

// 在某些不需要參數的 COM 函數中作為佔位符使用。
$empty = new VARIANT();

// 載入適當的型別程式庫。
com_load_typelib('Word.Application');

// 建立要使用的物件。
$word = new COM('word.application') or die('無法載入 Word');
print
"已載入 Word,版本 {$word->Version}\n";

// 開啟一個新的文件,其中包含名為 YourName 和 YourAge 的書籤。
$word->Documents->Open('C:/Unfilled.DOC');

// 從表單填入資訊。
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // 注意使用來自型別程式庫的 wdGoToBookmark,以及 $empty 的用法。
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// 儲存文件、關閉 Word 並結束程式。
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word = null;
print
"Word 已關閉。\n";
?>

範例文件內容如下...

哈囉 [YourName 書籤],你今年 [YourAge 書籤] 歲。

並且呼叫方式會是...

word.php?YourName=Richard%20Quadling&YourAge=35

此致,

Richard.
0
pchason at juno dot com
21 年前
我花了數天搜尋如何設定多欄 HTML 輸出網格,在建立 ADODB 連線時不使用陣列。我找不到任何相關資訊,所以我自己研究出來了。其實很簡單。我真希望自己早點嘗試。下面是有資料庫連線的程式碼,並附有註解...

<html>
<body>
<table>
<?php
// 建立資料庫連線
$conn = new COM("ADODB.Connection");
$dsn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("mydb.mdb");
$conn->Open($dsn);
// 使用 SQL 字串提取資料
$rs = $conn->Execute("select clients from web");
$clients = $rs->Fields(1);
// 開始多欄資料輸出
$i = 0;
$columns = 5;
while (!
$rs->EOF){
// 如果 $i 等於 0,則開始新的一列
if($i == 0){
echo
"<tr>";
}
// 然後開始在列中寫入儲存格,將 $i 加 1,並移動到下一筆記錄
echo "<td>" . $clients->value . "</td>";
$i++;
$rs->movenext();
// 一旦 $i 遞增到等於 $columns,則結束列,
// 並將 $i 設定為 0 以重新開始此過程
if($i == $columns || $rs->EOF) {
echo
"</tr>";
$i = 0;
}
}
// 結束多欄資料輸出

// 關閉 ADO 連線並釋放資源
$rs->Close();
$conn->Close();
$rs = null;
$conn = null; ?>
</table>
</body>
</html>
-1
php at racinghippo dot co dot uk
21 年前
以參考方式傳遞/回傳參數
=========================================

有些 COM 函數不僅透過回傳值回傳數值,也會對以「參考方式」傳遞給它的參數變數執行操作。

RetVal = DoSomethingTo (myVariable)

單純在 myVariable 前面加上 '&' 並不會有效 - 您需要傳遞正確型別的 variant,如下所示

$myStringVariant = new VARIANT("覆寫我", VT_BSTR);
$result = $comobj->DoSomethingTo( &$myStringVariant );

variant 中的數值接著可以透過以下方式擷取

$theActualValue = $myStringVariant->value;

您可以根據需要建立其他類型的 variant - 請參閱前述關於 VARIANT 型別的章節。
To Top