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
}