Re: Fwd: Code Optimization Help
| From: | Jochem Maas | Date: | Tue, 20 Sep 2005 14:08:54 +0000 |
| Subject: | Re: Fwd: Code Optimization Help | ||
| References: | 1 2 3 4 5 6 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-222771@lists.php.net to get a copy of this message | ||
Joseph Crawford wrote:
Jochem, I did attempt what you wanted me to try, however when i did that it just hung up on the OpenHeaders $this->obj->ActiveDocument->MailMerge->OpenHeaderSource($this->mm_data_dir.'/header.doc');maybe your Close() function should be different?: private function Close() { $this->obj->ActiveDocument->Close(); } but I still think your problem is the creation of multiple COM objects... the download on following page might give you a hint as to other methods which are available: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbawd11/html/WordVBAWelcome_HV01135786.asp and there is this: http://netevil.org/talks/PHP-and-COM-2005.pdf which might help (it's by Wez Furlong, one of the core php guys) sorry I can't help more.
I attempted this by removing the calls to quit, and just closing the active document so that it would keep the COM object open, however it just hung up on that line, i couldnt even get zend studio to spit an error for me. On 9/20/05, *Jochem Maas* <jochem@iamjochem.com <mailto:jochem@iamjochem.com>> wrote:Joseph Crawford wrote:I am not sure where you got the idea that it is creating aninstance of wordI got the idea from your code, but I just gave it a quick glance... that said you instantiate a new COM object in at least 3 places...CreateHeader() CreateDataSource() CreateDocument()which you mention might be the 'naughty' methods ... possibly then the culprit is still the slow instantiation of multiple COM objects?for every record, but it creates one instance then loops throughthe recordsusing that one instance. On 9/20/05, Jochem Maas <jochem@iamjochem.com<mailto:jochem@iamjochem.com>> wrote:Joseph Crawford wrote:Hello Everyone, I have some code that is using COM to interact with MS Word tocreate amailmerge based on my mysql database, however it is running
dreadfully slow13.53846 seconds to be exact. This is only running on 34 records, i could
imagine running this on a few hundred records not to mention
thousand.Is
COM usually this slow? These load times i believe to be accurate
as theycome from zend studio's profiler. You can see screenshots of the profile @ http://codebowl.dontexist.net/bugs/MailMerge/ Below you will see my code,
anything you guys see that i could do to speed this up quite a
bit iwould
appreciate it. It seems the naughty methods are CreateHeader, CreateDataSource, CreateDocument. CODE ===================================================== <?php class MailMerge { private $mm_data_dir; private $obj; private $fieldcnt; private $rowcnt; private $letter_template; private $envelope_template; public function __construct($list = null, $letter = 'Has_Site',$envelope =
'Envelope', $data_dir = 'data/mailmerge') { if(!is_array($list)) throw new Exception('Cannot Create A Mail MergeWith An
Empty List.');// an off topic thought... if (!is_array($list) || empty($list)) { throw new Exception(' ...
'); }more on topic ... you might try to make the com object a singleton rather than creating a new one for each record you are processing, and then clear the word document before starting a new record... I could imagine starting up an instance of Word for every record could be your bottleneck ... given the ammount of time it takes to start up an interactive instance of Word! (which is measured in seconds on my fairly up2date laptop). i.e. only do this line once, for instance
(untested):class MailMerge { static protected function getWord($clean = false) { static $obj; if (!isset($obj)) { $obj = new COM("word.application "); if ($obj instanceof COM) { throw new Exception('I have no Word(s)'); } } if ((boolean)$clean) { /* todo: make the Word instance as new */ } return $obj; } /* ... rest of class ... */ private function CreateHeaderFile() { $this->obj = self::getWord(); /* ... rest of method ... */ } }
$this->mm_data_dir = 'F:/htdocs/csaf/'.$data_dir; $this->list = $list; $this->letter_template = $letter; $this->envelope_template = $envelope; $this->initilize(); $this->CreateHeaderFile(); $this->CreateDataSource(); $this->CreateDocument($this->letter_template); $this->CreateDocument($this->envelope_template); } public function __destruct() { unlink($this->mm_data_dir.'/ds.doc'); unlink($this->mm_data_dir.'/header.doc'); } private function initilize() { $this->rowcnt = count($this->list); $this->fieldcnt = count($this->list[0]); } private function Close() { $this->obj->Documents->Close(); } private function Quit() { $this->obj->Quit(); } private function Release() { $this->obj = NULL; } private function CreateHeaderFile() { $this->obj = new COM("word.application") or die('Couldnt load
Word!');if(!is_object($this->obj)) throw new Exception('Unable to
instanciateWord!'); $this->obj->Documents->Add(); $this->obj->ActiveDocument->Tables->Add($this->obj->Selection->Range,1,$this->fieldcnt);
for($i = 0; $i <= $this->rowcnt; $i++) { foreach($this->list[$i] as $key => $value) { $this->obj->Selection->TypeText($key); $this->obj->Selection->MoveRight(); } } $this->obj->ActiveDocument->SaveAs($this->mm_data_dir.'/header.doc'); $this->Close(); $this->Quit(); $this->Release(); } private function CreateDataSource() { $this->obj = new COM("word.application"); if(!is_object($this->obj)) throw new Exception('Unable to
instanciateWord!'); $this->obj->Documents->Add(); $this->obj->ActiveDocument->Tables->Add($this->obj->Selection->Range,$this->rowcnt,$this->fieldcnt);
for($i = 0; $i <= $this->rowcnt; $i++) { foreach($this->list[$i] as $key => $value) { $this->obj->Selection->TypeText($value); $this->obj->Selection->MoveRight(); } } $this->obj->ActiveDocument->SaveAs($this->mm_data_dir.'/ds.doc'); $this->Close(); $this->Quit(); $this->Release(); } private function CreateDocument($template) { $this->obj = new COM("word.application"); if(!is_object($this->obj)) throw new Exception('Unable to
instanciateWord!'); $this->obj->Documents->Open($this->mm_data_dir.'/'.$template.'.dot'); $this->obj->ActiveDocument->MailMerge->OpenHeaderSource($this->mm_data_dir.'/header.doc');
-- Joseph Crawford Jr. Codebowl Solutions, Inc. 1-802-671-2021 codebowl@gmail.com <mailto:codebowl@gmail.com>$this->obj->ActiveDocument->MailMerge->OpenDataSource($this->mm_data_dir.'/ds.doc');$this->obj->ActiveDocument->MailMerge->Execute();$this->obj->ActiveDocument->SaveAs($this->mm_data_dir.'/'.$template.'.doc');$this->Close(); $this->Quit(); $this->Release(); } } ?>