viewmaindialog
// MainDialog.cpp : Implementation of CMainDialog
// This will fill a tree control like this: // libname // memname // variableName // memname // ... #include "stdafx.h" #include "MainDialog.h"
// atlcontrols.h is shipped with a sample atl program with vc #include "atlcontrols.h" #import "sas.tlb"
#import "SASWMan.dll" #import "c:\program files\common files\system\ado\msado15.dll" rename("EOF", "adoEOF")
///////////////////////////////////////////////////////////////////////////// // CMainDialog LRESULT CMainDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
unsigned long i; long j;
// This is defined in atlcontrols.h; it is not part of Win32.
ATLControls::CTreeViewCtrl ctrlTreeView; ctrlTreeView.Attach(GetDlgItem(IDC_TREE1)); BSTR xmlInfo; HRESULT hr; _bstr_t strSource; SASWorkspaceManager::IWorkspaceManager2Ptr pIWorkspaceManager; SAS::IWorkspacePtr pIWorkspace; SASWorkspaceManager::IServerDef2Ptr pIServerDef = NULL; hr = pIWorkspaceManager.CreateInstance("SASWorkspaceManager.WorkspaceManager.1");
ADODB::_ConnectionPtr obConnection = NULL; ADODB::_RecordsetPtr obRecordset = NULL; hr = obRecordset.CreateInstance( __uuidof( ADODB::Recordset )); hr = obConnection.CreateInstance( __uuidof( ADODB::Connection ));
// The smart pointers will throw an exception if any function returns a bad hr, so we // don't need to check for hr's. try{ pIWorkspaceManager->Workspaces->UseXMLInErrorInfo = false; // Start SAS and get the Workspace //***** Local SAS Code **************** pIWorkspace = pIWorkspaceManager->Workspaces->CreateWorkspaceByServer( _bstr_t("localsas"), SASWorkspaceManager::VisibilityProcess, NULL, _bstr_t(""), _bstr_t(""), &xmlInfo); //***** End Local SAS Code ************ //***** Remote SAS Code *************** //pIServerDef.CreateInstance("SASWorkspaceManager.ServerDef"); //pIServerDef->Port = 5307; //pIServerDef->Protocol = SASWorkspaceManager::ProtocolBridge; //pIServerDef->PutMachineDNSName(_bstr_t("your.iomserver.com")); //pIWorkspace = pIWorkspaceManager->Workspaces->CreateWorkspaceByServer( // _bstr_t("remotesas"), SASWorkspaceManager::VisibilityProcess, // pIServerDef, _bstr_t("username"), _bstr_t("password"), &xmlInfo); //***** End Remote SAS Code *********** //Valid Protocols //SASWorkspaceManager::ProtocolCom //SASWorkspaceManager::ProtocolBridge
// We can run some SAS code here to create a dataset or assign a libname // or whatever. You can also use a StoredProcess, which is where the SAS // code is already on the SAS server and you just tell SAS to run it; you // can also pass in parameters from your program to the StoredProcess. // That call might look something like this (assuming there is already a // program on the SAS server called init.sas) // SAS::IStoredProcessServicePtr pIStoredProcess; // pIStoredProcess = pIWorkspace->LanguageService->StoredProcessService; // pIStoredProcess->PutRepository(_bstr_t("c:\\stocks\\Repository")); // pIStoredProcess->Execute(_bstr_t("init"), _bstr_t("x=5"));
pIWorkspace->LanguageService->Submit( "libname stocks 'c:\\'; data a; x=5; y=10; run;");
// Output the SAS log to the Debug window OutputDebugString(pIWorkspace->LanguageService->FlushLog(10000)); // Connect the ADO Connection to the Workspace we created _bstr_t strConnect( "Provider=SAS.IOMProvider.1; SAS Workspace ID=" ); strConnect = strConnect + pIWorkspace->UniqueIdentifier;
hr = obConnection->Open(strConnect, _bstr_t(""), _bstr_t(""), NULL);
// Get a safearray containing all the assigned libraries SAFEARRAY *psaLibrefNames; pIWorkspace->DataService->ListLibrefs(&psaLibrefNames);
BSTR *pData; HTREEITEM treeLibnameItem; HTREEITEM treeMemnameItem;
SafeArrayAccessData(psaLibrefNames, (void **)&pData); ADODB::_RecordsetPtr obMembers = NULL; hr = obMembers.CreateInstance( __uuidof( ADODB::Recordset ));
// Add each assigned library to the treeview for (i=0; i<psaLibrefNames->rgsabound->cElements; i++) { _bstr_t strLibname(pData[i]);
treeLibnameItem = ctrlTreeView.InsertItem(strLibname, NULL, NULL);
// Add each dataset from each library to the treeview. // sashelp.vmember is a dataset the SAS system maintains that contains all the // contents of all libraries on the system. strSource = "select * from sashelp.vmember where libname='" + strLibname + "' and memtype='DATA'"; obMembers->Open( strSource, _variant_t((IDispatch *)obConnection), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText );
// Add each variable(observation) from each dataset to the treeview while (!obMembers->adoEOF) { _bstr_t strMemname(obMembers->Fields->GetItem( _variant_t( "memname" ) )->Value);
treeMemnameItem = ctrlTreeView.InsertItem(strMemname, treeLibnameItem, NULL);
strSource = strLibname + "." + strMemname; try{ obRecordset->Open( strSource, _variant_t((IDispatch *)obConnection), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdTableDirect );
long fieldCount = obRecordset->Fields->Count;
for (j=0; j< fieldCount; j++) { ctrlTreeView.InsertItem( (_bstr_t)(obRecordset->Fields->GetItem( _variant_t( j ) )->Name), treeMemnameItem, NULL); }
obRecordset->Close(); } catch(_com_error e){ OutputDebugString(e.Description()); }
obMembers->MoveNext(); }
obMembers->Close(); }
SafeArrayUnaccessData(psaLibrefNames); SafeArrayDestroy(psaLibrefNames); pIWorkspaceManager->Workspaces->RemoveWorkspace(pIWorkspace); pIWorkspace->Close(); // Ensure that the SAS process is terminated. } catch(_com_error e){ OutputDebugString(e.Description()); ::MessageBox(NULL, e.Description(), "Error Caught!", MB_OK); for (j=0; j<obConnection->Errors->Count; j++) { OutputDebugString(_bstr_t(obConnection->Errors->GetItem(j)->Description)); } OutputDebugString(_bstr_t(obConnection->Errors->Count)); return 1; }
::MessageBox( NULL, "Success!", "", MB_OK );
return 1; // Let the system set the focus }

|