Blog criado para documentar e disseminar o conhecimento tecnológico adquirido por Thiago Campos Pereira e colaboradores.
quarta-feira, agosto 19, 2009
PowerBuilder 11 X Oracle
PowerBuilder - Migração para Versão 11.5 - Problemas...
estou fazendo alguns estudos sobre a migração do PowerBuilder da versão 9 para a versão 11.5. Desta forma, estou levantando problemas que posso enfrentar. A principio, identifiquei o problema abaixo:
- Performance de desenvolvimento é 1/3 da performance do PB9. Este problema foi repassado a Sybase que nos informou que devido a quantidade de recursos adicionados ao PB 10 e 11 a DataWindow ficou mais pesada e que é normal este delay, não sendo considerado um problema e sem previsão de melhoria.
PowerBuilder - Geração automatica de executável com o Team Foundation
<
Exec WorkingDirectory="$(SolutionRoot)" Command="start /wait Pwrgn11.exe /J="$(SolutionRoot)\TeamBuildTypes\ProjectName.gen"/PBG"/>
<
Exec WorkingDirectory="$(SolutionRoot)" Command="start /wait Pwrgn11.exe /A="$(SolutionRoot)\TeamBuildTypes\ProjectName.gen""/>
I am finally closing this thread. anybody needs any help please let me know.
THANKS.
Mais informações em http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/617dd2f5-3538-4bcb-9101-15a49445df23
domingo, janeiro 21, 2007
Boicote ao Skype
desde 18/01/2007 o SKype está cobrando uma tarifa de 0,09 centavos para cada ligação que você fizer no SkypeOut. Para nos defendermos desta cobrança abusiva, sugiro iniciarmos uma boicote ao SkypeOut, utilizando o programa concorrente GIZMO (http://www.gizmoproject.com/) ou outro a sua escolha.
A grande vantagem do Gizmo é que o mesmo tem caixa posta grátis e tarifas mais baratas para vários locais, inclusive Brasil e USA.
Leia mais detalhes da cobrança abusiva em http://idgnow.uol.com.br/telecom/2007/01/19/idgnoticia.2007-01-19.7152325690/IDGNoticia_view
sexta-feira, janeiro 05, 2007
PowerBuilder – Utilizando o Team Foundation Source Control ao invés do Visual SourceSafe
Entre os problemas, podemos citar:
1 – Fontes corrompidos: Como a base de dados do VSS é muita arcaica, sendo composta por vários arquivos em disco e sem nenhum controle transacional, é muito comum termos um fonte corrompido devido a falhas de energia o cancelamento de aplicativos. O que gera muito trabalho para o administrador do VSS e muitas vezes paralisa as atividades da equipe de desenvolvimento;
2 – Backup da Base de Dados do VSS: Como o BD do VSS é composto por milhares de arquivos, o Windows demora muito tempo para realizar o Backup destes arquivos. Em uma base de dados de 5 GB, o Windows demora 6 horas para copiar os arquivos do VSS para uma área de Backup.
3 – Analyze: Este é o aplicativo responsável por gerenciar os problemas na base de dados do VSS. Ele é a muito lento e exige que ninguém utilize a base de dados durante a execução. Por exemplo, em uma base de dados de 5GB, o Analyze demora 24 horas para executar. Lembrando que a Microsoft recomenda que este deve ser executado semanalmente. Outro problema é que nem sempre ele resolve todos os problemas, inclusive, podendo causar novos problemas ao remover um arquivo corrompido;
4 – Lentidão: Outro problema é a lentidão para executar algumas operações, como o Share/branch, delete e pesquisa na base de dados;
5 – Customização limitada e complexa: Caso seja necessário criar consulta ou procedimento que acessem diretamente a base do VSS, o custo se torna muito alto, pois é necessário recursos altamente especializados e o tempo para esta tarefa é muito grande;
6 – Software Arcaico: Devemos lembrar que a estrutura do VSS existente hoje, no ínicio de 2007 é praticamente a mesma existente em 1996. Dez anos para informática é muito tempo!!
A partir dos problemas acima, resolvi estudar outro software de controle de versão.
Como utilizamos VisualStudio 2005 e o PowerBuilder para desenvolvimento, resolvi analisar o Team Foundation Source Control ( TFSC) que é a evolução natural para o Visual SourceSafe.
A primeira questão é se o mesmo seria compatível com o PowerBuilder 9. Realizei algumas pesquisas e descobri que a Microsoft lançou uma API que realiza a compatibilidade entre outras aplicações e o TFSC, chamada de Visual Studio team Foundation Server MSSCCI Provider ( http://www.microsoft.com/downloads/details.aspx?familyid=87E1FFBD-A484-4C3A-8776-D560AB1E6198&displaylang=en ). De acordo com as informações do site, ela é compatível com PowerBuilder 10.5. Investigando melhor, descobri no Blog do desenvolvedor da Microsoft responsável pelo produto, que eles apenas testaram com o PowerBuilder 10.5, mas não quer dizer que não é compatível com outras versões do PowerBuilder. Testei com o PowerBuilder 9.0.3 Build 8784 e funcionou perfeitamente.
Já estou em fase final de deste e essa versão trouxe muitas melhorias e piorou algumas funcionalidades. Abaixo vai uma relação das vantagens e desvantagens existentes:
* Vantagens
- Utiliza Banco de Dados SQL Server;
- Não corre risco de corromper;
- rotinas de manutenção são a mesma de banco de dados (Backup e Reindex, processos rápidos e automatizados);
- Mais recursos para Administração (Permissões, Grupos de usuário e tipos de acesso);
- Maior segurança (Integrado com a segurança do Windows, não necessitando criar usuários no próprio VSS);
- Maior Velocidade no acesso e gravação dos dados (Adicionar objetos, Refresh Status e GetLatestVersion);
- Permite fazer GetLatestVersion de um HotFixes especifico;
- Manutenção pode ser feita on-line, com os usuários utilizando;
- Permite fazer Merge de uma versão inteira ou de objetos específicos;
- Não há necessidade de Archive, pois o SQL Server gerencia bem a formato da base;
- Possibilidade de criar novos índices nas tabelas e melhorar o desempenho da base de dados do VSS;
- Possibilidade de se criar consultas direto na base de dados do VSS;
- Permite acesso via http, inclusive, é possível colocar a base de dados fora da empresa, em um DataCenter;
- Resolveu problema do simbolo de alterado quando o objeto é identico
- É possível Criar vários "Bases de dados" para projetos diferentes e com permissões diferentes.
* Desvantagens
- Problema ao registrar o primeiro objeto da PBL, onde deve-se observar o limite de no máximo 25 objetos, para que o PBG seja criado corretamente;
- Complexidade para saber quais objetos foram alterados entre um label e outro;
- Novo e pouco utilizando com o PowerBuilder, o que pode ocorrer Bugs na utilização;
- Custo (Tem que comprar o TeamFoundation, SQLServer e SharePoint)
- Ao Mover o objeto tem que desconectar, mover o objeto e alterar o PBG manualmente (PBL de origem e destino) ;
- hardware Mínimo ( 1GB de memória, 20 GB HD e Processador de 2 GHZ);
Veredicto: Aprovado!!
quinta-feira, janeiro 04, 2007
Team Foundation – Instalação Complicada
A primeira dica é para ler este artigo até o final. A segunda dica é para seguir as instruções do manual de instalação, que pode ser obtido no endereço http://www.microsoft.com/downloads/details.aspx?familyid=E54BF6FF-026B-43A4-ADE4-A690388F310E&displaylang=en
Para começar, fiz a instalação em uma Máquina Virtual ou Virtual Machine (VM) utilizando o Microsoft Virtual Server.
O Primeiro problema que tive são os pré-requisitos existentes, que são:
1 – Criação dos usuários necessários para a instalação do TF;
2 – Windows 2003 SP 1;
3 – Internet Information Server (IIS);
4 – SQL Server 2000 ou superior (Optei por instalar o SQL Server 2005);
5 – Service Pack do SQL Server (Essa opção pode ser substituída por uma correção no Analyse Server que pode ser baixada da Internet);
6 – DotNet FrameWork 2.0;
7 – Correção do DotNet Framework 2.0 (A correção está dentro da CD do TF);
8 – Share Point Service (SPS) 2.0;
No inicio da Instalação do TF, ele exibe um relatório com os pré-requisitos que estão faltando. A partir deste relatório, instalei os pré-requisitos da forma que eu acho melhor e ai começaram os problemas.
Apenas lembrando para cada problema abaixo, eu formatei a VM e reinstalei tudo novamente. Escolhi este procedimento, pois um erro pode provocar outro erro e muitas vezes você perde mais tempo tento resolver um erro do que refazendo toda instalação da forma correta.
Na Instalação do SQL Server, eu instalei como Acento Insesitive, sendo que TF necessita que seja Acento Sensitive.
Na Instalação o IIS, eu instalei o Front Page Extension, sendo que a melhor opção é você não instalar essa opção.
Na Instalação do SPS 2.0, não me exibiu nenhuma opção para escolher e eu instalei normalmente. Após a instalação, o TF me exibiu uma mensagem dizendo que eu deveria instalar o SPS como Server Farm. Mas como não me foi exibida essa opção, fiquei totalmente perdido. Após entrar em vários Fóruns e tentar várias soluções sem sucesso, lembrei que não havia colocado o meu servidor no Domínio e poderia ser a causa do problema. Reinstalei o Windows 2003 e coloquei o mesmo no domínio. Na hora da instalação do SPS, apareceu a opção se Server Farm, resolvendo o problema.
Mas quando pensei que estava tudo funcionando, o relatório de pré-requisitos me retorna tudo OK e a Instalação do TF funcionou, comecei a ter um erro estranho, onde ele não consegui inicializar o Site de administração.
Neste momento e depois de perder uma semana de serviço, resolvi ler a documentação de instalação e seguir os passos. Então eu descobri que tudo o que eu tinha resolvido anteriormente e quebrado a cabeça estava na documentação. Também descobri o que estava originando este último problema. Como não segui os procedimentos que relação aos usuários necessários para instalação, utilizando os usuários locais da minha máquina, alguns serviços não foram configurados da forma correta.
Após formatar a VM e reinstalar tudo novamente, agora seguindo a documentação, tudo funcionou perfeitamente na primeira vez e consegui realizar meus testes com sucesso.
Apenas uma dica para quem vai realizar testes. O TF exige muito Hardware, principalmente memória. Abaixo vai a configuração da máquina que utilizei para realizar os testes:
- Máquina Física
* Memória: 1 GB;
* HD: 120 GB;
* Processador: Pentium IV Dual 3.2 Ghz;
- Máquina Virtual
* Memória: 600 MB ( Após instalar tudo, a VM gasta 500 MB apenas para iniciar. Em algumas situações, chegou a consumir 700MB, gerando paginação e ficando lenta);
* HD: 12 GB (Após a instalação, foram gastados 8 GB);
* processador: 90% do processador principal, o que foi suficiente;
Boa Sorte!!!
Windows – Arquivo de Help da Microsoft bloqueado (CHM)
A principio, pensei que o problema era com a minha máquina ou com a rede da empresa. Mas depois de tentar ler o arquivo em 3 locais diferentes, descartei está possibilidade.
Como segunda possibilidade, pensei que a documentação da Microsoft estava com problema, então tentei acessar outros arquivos CHM e todos retornaram o mesmo erro.
Como precisava da documentação, pesquisei na Internet e encontrei um artigo no endereço http://support.microsoft.com/kb/896054/ que explica a causa do problema e como resolver.
Resumindo, a Microsoft liberou uma atualização de segurança para Windows XP que bloqueia o conteúdo deste arquivo, que é um conteúdo HTML e pode conter código perigoso para a máquina. Para liberar o conteúdo, você tem que editar uma chave do Registry, manualmente.
Ponto negativo para a Microsoft, pois já que bloquearam os arquivos CHM, deveria liberar a sua documentação em outro formato, como Word ou PDF.
Fico imaginando a quantidade de pessoas que não tiveram paciência para encontrar a solução e desistiram de utilizar uma ferramenta por falta de conhecimento
sábado, dezembro 16, 2006
PowerBuilder - Documentando o código fonte
Por isso, resolvi publicar dois sites que possuí ferramentas com este objetivo.
http://www.pbdr.com/
http://www.novalys.net/
quinta-feira, dezembro 14, 2006
Windows - Recuperando arquivos excluídos
http://www.batori.com.br/noticcon.asp?arquivo=seg06121305.htm
quarta-feira, dezembro 13, 2006
PowerBuilder - Utilizando FTP
/***Declaração de Estrutura
type win32_find_dataa from structure
unsignedlong dwfileattributes
filetime ftcreationtime
filetime ftlastaccesstime
filetime ftlastwritetime
unsignedlong nfilesizehigh
unsignedlong nfilesizelow
unsignedlong dwreserved0
unsignedlong dwreserved1
character cfilename[260]
character calternatefilename[14]
end type
/*** Declaração de Funções externas
function long InternetOpenA(string lpszAgent, long dwAccessType, string lpszProxyName, string lpszProxyBypass, long dwFlags )&
library "wininet.dll"
function long InternetConnectA(long hInternet, string lpszServerName, int nServerPort, string lpszUsername, &
string lpszPassword, long dwService, long dwFlags, long dwContext) library "wininet.dll"
Function Boolean FtpSetCurrentDirectoryA (long hFtpSession, string lpszDirectory) library "wininet.dll"
Function boolean FtpCreateDirectoryA(Long hConnect, string lpszDirectory) library 'wininet.dll';
Function boolean FtpPutFileA(long hConnect, string lpszLocalFile, string lpszNewRemoteFile, long dwFlags, &
long dwContext) library "wininet.dll"
Function boolean FtpGetFileA(long hConnect, string lpszRemoteFile, string lpszNewFile, boolean fFailIfExists, &
long dwFlagsAndAttributes, long dwFlags, long dwContext) library 'wininet.dll'
Function boolean FtpRenameFileA(Long hConnect, string lpszExisting, string lpszNew) library 'wininet.dll';
Function boolean FtpDeleteFileA(Long hConnect, string lpszFileName) library 'wininet.dll';
Function long InternetCloseHandle(long hInet) library "wininet.dll"
Function long FtpFindFirstFileA (Long hFtpSession , string lpszSearchFile, ref WIN32_FIND_DATAA lpFindFileData , long dwFlags, long dwContent) library "wininet.dll"
Function boolean InternetFindNextFileA (Long hFind, ref WIN32_FIND_DATAA lpvFindData) library "wininet.dll"
/*** Variáveis de instáncia
Constant Public long INTERNET_DEFAULT_FTP_PORT = 21, &
INTERNET_SERVICE_FTP = 1, &
FTP_TRANSFER_TYPE_ASCII = 1, &
FTP_TRANSFER_TYPE_BINARY = 2
Public ProtectedWrite long uol_Hnd_open, uol_Hnd_Conexao
Public ProtectedWrite string uos_servidor, uos_dir_atual, uos_usuario, uos_aplicacao, uos_ftp_dir
Private string uos_senha
/**** Função para conectar no FTP
public function long of_conecta_ftp (string p_aplicacao, string p_servername, string p_usuario, string p_senha);
/*----------------------------------------------------------------------------------*/
/* FAZ A CONEXÃO COM O SERVIDOR PARA TRANSFERÊNCIA VIA FTP */
/* PARÂMETROS: p_aplicacao: Nome da aplicação
p_servername: 'ftp.zzzzz.com.br' ou endereço IP Ex.: '255.255.255.255'
p_usuario e p_senha*/
string vlsnulo
setnull(vlsnulo)
uos_servidor = p_servername
uos_usuario= p_usuario
uos_senha = p_senha
uos_aplicacao = p_aplicacao
uos_ftp_dir = ''
uol_hnd_open = internetopena(uos_aplicacao , 1, vlsnulo, vlsnulo, 0)
if uol_hnd_open = 0 or isnull(uol_hnd_open) then
vismsg = 'Erro ao abrir a conexão. Função API InternetOpen'
return - 1
end if
uol_hnd_conexao= internetconnecta( uol_hnd_open, uos_servidor, &
0,uos_usuario, uos_senha, 1, 0, 0)
if uol_hnd_conexao= 0 or isnull(uol_hnd_conexao) then
vismsg= 'Erro ao abrir a conexão. Função API InternetConnect'
internetclosehandle( uol_hnd_open)
return - 1
end if
return 1
end function
/**** Função para desconectar do FTP
public function long of_desconecta_ftp ();
internetclosehandle( uol_hnd_conexao)
internetclosehandle( uol_hnd_open )
uos_usuario = ''
uos_senha = ''
uos_servidor = ''
uos_aplicacao = ''
uos_dir_atual = ''
uol_hnd_conexao = 0
uol_hnd_open = 0
return 1
end function
/**** Troca o diretório do FTP
public function long of_ftp_set_dir (string p_dir);
if not FtpSetCurrentDirectoryA ( uol_hnd_conexao , p_dir ) then
vismsg = 'Não foi possível encontrar a pasta ' + p_dir + '!'
return -1
end if
//Altera a propriedade uos_ftp_dir (Pasta corrente)
long vll_pos
if p_dir = '\' then
uos_ftp_dir = ''
elseif p_dir = '..' and uos_ftp_dir <> '' then
do while pos(uos_ftp_dir, '\', vll_pos + 1) > 0
vll_pos = pos(uos_ftp_dir, '\', vll_pos + 1)
loop
if vll_pos > 0 then
uos_ftp_dir = left(uos_ftp_dir , vll_pos - 1)
else
uos_ftp_dir = ''
end if
else
uos_ftp_dir += '\' + p_dir
end if
////////////////////
return 1
end function
/**** Renomeia arquivo no FTP
public function long of_ftp_renamefile (string p_nome_ant, string p_nome_atu);
if not FtpRenameFileA(uol_hnd_conexao, p_nome_ant, p_nome_atu) then
vismsg = 'Não foi possível renomear o arquivo ' + uos_ftp_dir + '\'+ p_nome_ant + ' para ' + uos_ftp_dir + &
'\'+ p_nome_atu + '!'
return -1
end if
return 1
end function
/**** Envia arquivo para o FTP
public function long of_ftp_putfile (string p_arquivo_local, string p_arquivo_ftp);
if not ftpputfilea( uol_hnd_conexao, p_arquivo_local, p_arquivo_ftp, ftp_transfer_type_ascii, 0) then
vismsg = 'Erro ao transferir arquivo ' + p_arquivo_local + ' via FTP!'
return -1
end if
return 1
end function
/**** Baixa arquivo do FTP
public function long of_ftp_getfile (string p_remoto, string p_local);
if not FtpGetFileA(uol_hnd_conexao, p_remoto , p_local, false, 0, 1, 0) then
vismsg = 'Não foi possível fazer o download do arquivo '+ uos_ftp_dir + '\'+ p_remoto +' via FTP!'
return -1
end if
return 1
end function
/**** Deleta arquivo do FTP
public function long of_ftp_deletefile (string p_arquivo);if not FTPDeleteFileA(uol_hnd_conexao, p_arquivo) then
vismsg = 'Não foi possível excluir o arquivo ' + uos_ftp_dir + '\'+ p_arquivo + '!'
return -1
end if
return 1
end function
/**** Cria Diretório no FTP
public function long of_ftp_cria_dir (string p_dir);if not this.ftpcreatedirectorya( uol_hnd_conexao , p_dir ) then
vismsg = 'Não foi criar a pasta ' + p_dir + '!'
return -1
end if
return 1
end function
/**** Lista arquivo e diretórios do FTP
public function integer of_ftp_lista_arquivos (string p_filter, ref string p_arquivos[]);
// DESCRIÇÃO:
// * Lista os arquivos existentes no FTP
//
// ARGUMENTOS DE ENTRADA:
// * sfilter : Filtro utilizado para diretórios
// * p_arquivos : Lista de arquivos retornados
//
// RETORNO:
// * 1 : Sucesso
// * -1 : Erro
// * 0 : Registro não encontrado
//
// OBSERVAÇÃO:
// * Lista dos atributos retornados para arquivos
// Public Const FILE_ATTRIBUTE_READONLY = &H1
// Public Const FILE_ATTRIBUTE_HIDDEN = &H2
// Public Const FILE_ATTRIBUTE_SYSTEM = &H4
// Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
// Public Const FILE_ATTRIBUTE_ARCHIVE = &H20
// Public Const FILE_ATTRIBUTE_NORMAL = &H80
// Public Const FILE_ATTRIBUTE_TEMPORARY = &H100
// Public Const FILE_ATTRIBUTE_COMPRESSED = &H800
// Public Const FILE_ATTRIBUTE_OFFLINE = &H1000
//
// CRIADO POR :
// 12/12/2006 - Thiago Campos Pereira
// ALTERADO POR :
//
//========================================================================
long VLLhandleFind, VLLRet, VLLItem
string vlsAux
WIN32_FIND_DATAA VLstrData
//Procura primeiro arquivo no FTP
VLLhandleFind = FtpFindFirstFileA(uol_hnd_conexao, p_Filter, VLstrData, 0, 0)
//Se não encontrar arquivos, sai da função
If VLLhandleFind = 0 then return 1
//Se encontrou arquivo, realizar loop preenchendo vetor com diretórios
do
//Verificar se é arquivo e se não é diretorno
if mod(VLstrData.dwfileattributes , 128) = 0 then
//Se for diretório, armazena nome do diretório
vlsAux = ''
for VLLItem = 1 to upperbound(VLstrData.cfilename)
//No momento que encontrar o caracter 0, quer dizer que é o final do nome do diretório
if asc(VLstrData.cfilename[VLLItem]) = 0 then
p_arquivos[upperbound(p_arquivos) + 1] = vlsAux
exit
else
vlsAux = vlsAux + VLstrData.cfilename[VLLItem]
end if
next
end if
//Procura próximo diretório
if not InternetFindNextFileA(VLLhandleFind, VLstrData) then
VLLhandleFind = 0
end if
loop while VLLhandleFind > 0
return 1
end function
segunda-feira, dezembro 11, 2006
PowerBuilder - Listando Arquivos de um diretório
Recentemente, juntei algumas informações na Web e criei o código abaixo, que devolve em um vetor a lista de arquivos de arquivos de uma pasta, criando o ListBox e window dinamicamente.
/*INICIO Da FUnção
Salve o Conteúdo abaixo em um arquivo com o nome f_dir_list.SRF e importe para dentro da sua library*/
global type f_dir_list from function_object
end type
forward prototypes
global function long f_dir_list (string p_diretorio, string p_filtro, integer p_tipo_arquivo, ref string p_arquivos[])
end prototypes
global function long f_dir_list (string p_diretorio, string p_filtro, integer p_tipo_arquivo, ref string p_arquivos[]);
// DESCRIÇÃO:
// * Busca os arquivos de um diretório//
// ARGUMENTOS DE ENTRADA:
// * p_diretorio : Diretorio onde será feito a pesquisa. Se está variável estiver vazia, pesquisa o diretório corrente
// * p_filtro : Filtro utilizado no diretório. Se está variável estiver vazia, lista todos os arquivos
// * p_tipo_arquivo : Tipo do arquivo, conforme lista abaixo, sendo que o Default é 0 + 2 + 4
// - 0 : Arquivos de Leitura e gravação
// - 1 : Arquivos somente leitura
// - 2 : Arquivos Ocultos
// - 4 : Arquivos do Sistema
// - 16 : Sub-Pastas
// - 32 : Arquivos modificados
// - 16384 : Drivers
// - 32768 : Todos os arquivos, exceto arquivo de leitura e gravção
// - Para recuperar a uniao de um ou mais tipos acima, some os valores.
// Por exemplo, para listar arquivos leitura e gravação, subdiretorios e drivers, use 0+16+16384 ou 16400.
// * p_arquivos : Retorna por referencia a lista de arquivos passados
//
// RETORNO:
// * 1 : Sucesso
// * -1 : Erro
// * 0 : não existe arquivos
//
// OBSERVAÇÃO:
//
// CRIADO POR :
// 29/11/2006 - Thiago Campos Pereira
// ALTERADO POR :
//
//========================================================================
//Variaveis
string vls_arquivos[]
window vlw_temp
listbox vllb_temp
int vli_items, vli_i
//Trata Parametros
If isnull(p_diretorio) then
p_diretorio = ""
else
//Verifica se existe a barra no diretorno
p_diretorio = trim(p_diretorio)
if right(p_diretorio,1) = "\" then
//Retira a barra, para fazer pesquisa de diretório
p_diretorio = mid(p_diretorio,1,len(p_diretorio) - 1)
end if
//Verifica se o diretório existe
IF not DirectoryExists(p_diretorio) then
return -1
end if
//Acrescenta barra
p_diretorio = p_diretorio + "\"
end if
if isnull(p_filtro) then p_filtro = "*.*"
if isnull(p_tipo_arquivo) then p_tipo_arquivo = 0 + 2 + 4
//Instancia Objetos
Open(vlw_temp)
vlw_temp.openUserObject( vllb_temp )
//Lista arquivosv
llb_temp.DirList( p_diretorio + p_filtro , p_tipo_arquivo )
//Passa pelos arquivos, gerando lista no array
vli_items = vllb_temp.TotalItems()
For vli_i = 1 to vli_items
vls_arquivos[ vli_i ] = vllb_temp.Text( vli_i )
Next
//Fecha instancia de objetos
vlw_temp.closeUserObject( vllb_temp )
Close( vlw_temp )
p_arquivos = vls_arquivos
return 1
end function
/*Fim da função*/
PowerBuilder – Build 8784 da Versão 9
A homologação foi um sucesso, sendo considerado o Build mais estável lançado pela Sybase nos últimos tempos.
Além de não detectarmos nenhum erro, resolveram todos os erros existentes, incluindo o problema quando se exclui um SubMenu do Menu ancestral e compila os descendentes.
******* Observação em 11/12/2006
Apenas para complementar o Post. Foi encontrado um Bug neste Build do PowerBuilder, onde a função dw_1.Object.DataWindow.Data.XML não respeita o “XML Declaration”, sempre gerando UTF-8 e trazendo problemas, principalmente relativos a acentos e caracteres especiais.
Para contornar o problema, utilizei o comando export da DataWindow, gravei um arquivo temporário e recuperei o conteúdo do arquivo através de FileOpen/FileRead.
PowerBuilder – Chamando uma aplicativo e aguardando a finalização
Este código é muito útil, principalmente quando você depende do resultado da outra aplicação, com a compactação de um arquivo, criptografia e etc...
Rodar um executavel e esperar
OleObject wsh
integer li_rc
CONSTANT integer MAXIMIZED = 3
CONSTANT integer MINIMIZED = 2
CONSTANT integer NORMAL = 1
CONSTANT boolean WAIT = TRUE
CONSTANT boolean NOWAIT = FALSE
wsh = CREATE OleObject
li_rc = wsh.ConnectToNewObject( "WScript.Shell" )
li_rc = wsh.Run("Notepad" , NORMAL, WAIT)
a msg abaixo so deve aparecer apos vc fechar o notepad
messagebox("ola", "teste")
se usar WAIT teremos em Run o codigo de retorno da aplicacao chamada
as constantes definidas podem tbm ser:
0 Hides the window and activates another window.
1 Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
2 Activates the window and displays it as a minimized window.
3 Activates the window and displays it as a maximized window.
4 Displays a window in its most recent size and position. The active window remains active.
5 Activates the window and displays it in its current size and position.
6 Minimizes the specified window and activates the next top-level window in the Z order.
7 Displays the window as a minimized window. The active window remains active.
8 Displays the window in its current state. The active window remains active.
9 Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
10 Sets the show state based on the state of the program that started the application.
quinta-feira, novembro 02, 2006
Oracle - Tabela temporária
PowerBuilder - Exportando dados de uma DataWindow para o MS Excel
Texto retirado do grupo de discussão de PB
Exportando dados de uma DataWindow para o Excel ultilizando OLE AutomationX
O PowerBuilder tem uma função para exportar dados para MS-Excel, mas ela limitada a dados de DML , com esta rotina podemos exportar toda a DataWindow. É um código simples e pode ser aperfeiçoado para uma aplicação mais complexa.
Passo 1 : Crie um nonvisual object salve ente objeto como nca_excel
Passo 2 : Crie uma função neste objeto com o nome de GetColumns Insira o código abaixo :
// Monta uma lista de todas as colunas da DW para exportação
Long ll_I, ll_Cols
ll_Cols = Long( adw_DW.Describe( 'datawindow.column.count' ) )
FOR ll_I = ll_cols TO 1 STEP -1
as_columns[ ll_I ] = adw_DW.Describe( '#' + String( ll_I ) + '.Name' )
NEXT
Passo 3: Crie uma função neste objeto com o nome de GetData. Esta função retorna um ANY. Propositalmente esta função foi colocada separada porque ela pode ser expandida e tratar ambém um Datasource.Insira o código abaixo :
Long ll_Col
Any la_A
IF al_Row > adw_DW.RowCount() THEN RETURN ""
ll_Col = Long( adw_DW.Describe( as_Column + ".ID" ) )
IF ll_Col > 0 THEN la_A = adw_DW.object.data.primary.current[ al_Row, ll_Col ]
RETURN la_A
Passo 4:Crie uma função neste objeto com o nome de inttocolumn .Esta função retorna um String.
// Converte a posição da coluna para o spreadsheet da coluna no Excel
String ls_Col
Integer li_Min, li_Max
IF ai_col <= 0 THEN RETURN ""
li_Max = ai_col / 26
li_Min = ai_col - ( li_Max * 26 )
IF li_Max > 0 THEN
ls_Col = Char( 64 + li_Max )
END IF
ls_Col += String( Char( 64 + li_Min ) )
RETURN ls_Col
Passo 5: Esta é a rotina principal do Objeto Crie uma função neste objeto com o nome de ExportToExcel .
// Exportando dados para o Excel
OleObject lole_OLE, lole_Sheet
String ls_Columns[]
Long ll_Row, ll_Col, ll_Cols
lole_OLE = CREATE OleObject
SetPointer( HourGlass! )
lole_OLE.ConnectToNewObject( 'excel.application' )
lole_OLE.Workbooks.Add
lole_sheet = lole_OLE.Application.ActiveWorkbook.WorkSheets[1]
this.GetColumns( adw_DW, ls_Columns )
ll_Cols = UpperBound( ls_Columns )
FOR ll_col = 1 TO ll_cols
lole_Sheet.Cells[ 1, ll_Col ] = ls_Columns[ ll_Col ]
NEXT
FOR ll_Row = 2 TO al_rows + 1
FOR ll_Col = 1 TO ll_cols
lole_Sheet.Cells[ ll_Row, ll_Col ] = this.GetData( adw_DW, ll_Row - 1, ls_Columns[ ll_Col ] )
NEXT
NEXT
lole_Sheet.Range( inttocolumn( 1 ) + "1:" + inttocolumn( ll_Cols ) + "1").Select
lole_OLE.Selection.Font.Bold = True
lole_Sheet.Range("A1:A1").Select
lole_Sheet.Columns( inttocolumn( 1 ) + ":" + inttocolumn( ll_cols ) ).EntireColumn.AutoFit
lole_OLE.Application.Visible = TRUE
// Código corrigido por Cristina da ( Multipla )
lole_OLE.Application.Workbooks(1).Saveas("C:\TESTE.XLS")
// lole_OLE.DisconnectObject() DESTROY lole_OLE
Salve o objeto..... Na sua aplicação em um botão ou item de menu escreva a chamada do objeto.
nca_excel lnca_Excel
lnca_Excel.ExportToExcel( dw_1, dw_1.RowCount() )
Onde " dw_1" é a DataWindow que você quer exportar.
Oracle - Gerando Número Sequencial de Registros
Pessoal,
Para quem não conhece, a função analítica do Oracle DENSE_RANK gera um número seqüencial para cada linha pertencente a um determinado grupo de linhas. Vejam o exemplo:
Suponhamos a tabela MUNICIPIO:
SGUF NOMMUN
AP Santana
AP Macapá
MG Belo Horizonte
MG Leopoldina
MG Cataguases
SP São Paulo
SP Campinas
SP Santos
SP Mogi-mirim
SP Jundiaí
Para gerar um seqüencial dos municípios, classificados alfabeticamente, DENTRO dos estados, podemos fazer:
SELECT sguf, DENSE_RANK () OVER (PARTITION BY sguf ORDER BY nommun) AS seq, nommun
FROM municipio
ORDER BY 1, 2;
Resultado:
sguf seq nommun
AP 1 Macapá
AP 2 Santana
MG 1 Belo Horizonte
MG 2 Cataguases
MG 3 Leopoldina
SP 1 Campinas
SP 2 Jundiaí
SP 3 Mogi-mirim
SP 4 Santos
SP 5 São Paulo
Mais detalhes podem ser obtidos na documentação do Oracle.
Diversos – Solução para Problemas com Monitor 15' LCD da Proview
Para resolvê-lo, é necessário um equipamento especifico que reinstala o FirmWare do equipamento.
O grande problema é que existe apenas um equipamento destes para todo o Brasil. Estou aguardando que este equipamento chegue a Belo Horizonte para realizar o conserto do meu monitor.
terça-feira, setembro 05, 2006
Palm - Tipos de Reset
Vire e mexe aparece novos usuários pedindo que se explique como fazer Resets e Hard Resets, pois bem aí vai tudo explicadinho:
1 - Soft Reset (reset suave)
Descrição:
Um soft reset diz a nosso PDA que deixe de fazer o que estava fazendo e comece de novo. Toda a informação que nele temos se conserva. Quando fazemos um soft reset uma tela de boas-vindas aparece e posteriormente nos leva a Preferências.
Procedimento:
Para fazer um soft reset é necessário introduzir pelo orifício atrás do PDA uma ponta de um clipes ou a ponta de algumas stylus apropriadas para isto (como a stylus das séries Tungstens), solte e pronto. É importante lembrar que é um toque leve e suave . JAMAIS USE PONTAS EXTREMAMENTE FINAS: EX.ALFINETES E AGULHAS.
2 - Duplo Soft Reset (duplo reset suave)
Descrição:
Se depois de fazer um soft reset no PDA o mesmo não se acende e está comprovado que tudo está bem (tem carga na bateria, o contraste (Brilho) está bem, etc) pode provar o duplo soft reset.
Procedimento:
Para fazer o duplo soft reset faz o mesmo que fez para o soft reset mas duas vezes seguidas (apertar 2 vezes o botão de reset atrás do palm em menos de 1 segundo)
3 - Warm Reset (reset medio)
Descrição:
Quando fazemos um warm reset em nosso PDA, ele se reinicia, mas ao fazer o carregamento das extensões (os hacks, os programas gestores de hacks, os patches do sistema, as preferências de alarmes, etc) pode ser esta a fonte do problema. Se for este o caso, o PDA te dará error cada vez que carregue, detendo o processo de carregamento dos programas ao tentar carregar a aplicação danificada. Como com o warm reset estas aplicações não se carregam, te dará a oportunidade de descobrir aquilo que está dando conflito com o sistema (normalmente apagando a fonte do problema) e reiniciando normalmente.
Procedimento:
Para fazer o warm reset aperta o botão de rolamento para cima (Direcional para cima) e simultaneamente aperte o botão de reset (atrás do palm), solta o botão de reset e quando aparecer a tela de boas-vindas solta o botão de rolamento (scroll). Deste modo não se perde a informação de PDA.
Se não estiver seguro de que programa está causando o "error", pode usar um programa como ResetEmu depois do warm reset para detectá-lo.http://www.79bmedia.com/resetemu/d_index.html
4 - Hard Reset (reset duro)
Descrição:
Com um hard reset você apagará tudo que estiver armazenado na memória do PDA, exceto as aplicações e preferências de fábrica (veja extendendo hard reset). Uma vez resetado o PDA será necessário restaurar tudo que tinha com um Hotsync (Se usas Palm OS 3.1 ou anterior e não tiver nenhum programa de Backup, como BackupBuddy ou BackupMan, é muito possivel que terá que reinstalar tudo outra vez.
Por isso, é aconselhavel só fazer o hard reset se todos os métodos anteriores não funcionaram ou se quiser eliminar toda a informação de seu PDA (Por exemplo: na hora de vender o seu PDA, ou se quiser fazer uma limpeza geral).
Procedimento:
Para fazer um hard reset siga os passos seguintes:
Mantenha apertado o botão de Liga-Desliga do PDA.
Ao mesmo tempo em que mantém apertado o botão Liga-Desliga, dê um reset por trás (no furinho).
Solta o botão de reset.
Quando o "logo" da Palm aparecer no visor, pode soltar o botão de Liga-Desliga.
Se tiver feito o procedimento corretamente, aparecerá uma mensagem no visor anunciando que você vai apagar toda a informação do seu PDA, permitindo confirmar a ação ao pressionar o botão direcional para cima. Se não quiser confirmar, é só apertar qualquer outro botão, que o mesmo só dará um soft reset.
5 - Extended Hard Reset (reset duro extendido)
Descrição:
O extended hard reset fará exatamente o mesmo que o hard reset, só com uma diferença: impede a criação de algumas bases de dados que o fabricante pôs (números de telefones do suporte nos contatos, alguma nota de texto no Notepad, as conexões em Preferências, sons de alarme MIDI, a mensagem de boa vinda no Correo, alguns exemplos de fotos, etc). Atente que apagará todas estas informações do seu PDA.
Se fizer o extended hard reset e logo instalar alguma aplicação, te dará um "error"; por isso é recomendável depois de um extended hard reset, entrar em cada uma das aplicações do palm (Agenda, contatos, notas, Correio, Tarefas, etc) para assegurar que foi criado a base de dados. Depois de um extended hard reset não terá mais sons de alarmes adicionais.
Procedimento:
Para fazer um extended hard reset:
Aperta e mantém apertado o botão de Liga-Desliga do seu PDA.
Enquanto o mantém apertado, dê um reset por trás.
Solte o botão de reset.
Quando o "logo" da Palm aparecer no visor, pode soltar o botão de Liga-Desliga.
Quando te perguntar se realmente deseja fazê-lo, aperte e MANTENHA APERTADO o botão direcional (scroll) para cima.
Lembre-se em mantê-lo apertado, ao mantê-lo apertado,aperte em qualquer ordem, o botão de AGENDA, CONTATOS, TAREFAS, e NOTAS.
Solte o botão direcional (scroll) e o processo do extended hard reset terminará.
Tenha em mente que se não chegar a apertar os 04 BOTÕES enquanto mantém o botão direcional para cima apertado, só ocorrerá um soft reset.
6 - FlashPro Reset
Descrição:
Nos PDAs que usam FlashPro (aplicação que permite acessar a memória Flash sobrando) é possivel que uma aplicação que estiver corrompida (danificada) na memória Flash impeça o PDA de responder aos RESETS.
Só deve usar o Flash Pro reset se seu PDA não reage frente à um Hard reset!
Procedimento:
Para fazê-lo:
Aperte e mantenha apertado o botão de Notas de seu PDA.
Enquanto o mantem apertado, dê um reset por trás.
Solte o botão de reset.
Quando o "logo" da Palm aparecer no visor, solte o botão de Notas.
Quando aparecer esta mensagem: "hit the ToDo button to reformat flash" no visor, aperta o botão de tarefas para completar o reset.
Todas as aplicações ou dados que estiverem armazenados na memória Flash se apagará e será necessário reinstalar-las.
7 - JackFlash Reset
Descrição:
Nos PDAS que usam Jack Flash (aplicação que permite acessar a memória Flash sobrando) é possivel haver movido uma aplicação danificada, corrompida ou que não pode ser instalada na memória Flash, impedindo que o PDA responda aos resets.
Procedimento:
Para fazer um JackFlash reset:
Aperte o botão de reset na parte de trás de seu PDA.
Solte o botão de reset.
Imediatamente depois do passo anterior, aperta e mantém apertado o botão de Notas. Se foi feito corretamente, soará um apito do alarme.
Uma vez que haja apitado o alarme, solte o botão de Notas.
Uma vez completado, use o JackFlash para mover as aplicações danificadas ou que não podem ser instaladas na memória Flash para a memória RAM.
O conteúdo da memória Flash não será visivel até que execute o JackFlash ou faça um hard reset. Este método não apaga nada da Flash, com o qual poderá iniciar bem seu PDA e usar o JackFlash para acessar as informações ali guardadas.
8 - Debug Reset
Descrição:
Algumas vezes, quando se tenta atualizar o Palm OS, pode haver uma interrupção no processo que pode ocasionar em seu PDA, uma falha no sistema, na qual ele acusa que seu PDA não tem sistema operativo.
Este reset abrirá O Nº de SERIE do seu PDA para permitir gravar diretamente na memória Flash o sistema operativo.
Este reset só deve ser feito quando na utilização de atualização do sistema nos for necessário.
Procedimento:
Para fazê-lo:
Aperta e mantém apertado o botão de rolagem(direcional) para baixo.
Aperta o botão de reset atrás.
Quando o "logo" da Palm aparecer no visor, solta o botão direcional.
Em alguns modelos de PDA aparecerá um pequeno quadro piscando em um canto do visor.
Aí estão todos os RESETS possíveis....(até o momento)
terça-feira, agosto 22, 2006
Oracle – Diferença no Group By no 10G
A partir do Oracle 10G, o Order By não ocorre mais, sendo necessário realizar a ordenação manual. Este procedimento está documentado no manual do Oracle 10G.
A partir desta mudança vai uma dica. Nunca confie no que o SGBD faz implicitamente. Se você quer o resultado do Group By ordenado, utilize o Order By para garantir isso.
Oracle - Trabalhando com duas transações
Eu tinha um bloco pl/sql que, apesar de ter alguns delete, insert e update no seu conteúdo, deveria fazer um commit apenas no final da execução, geralmente o processamento é feito em segundos. Acontece que o update, sem um motivo aparente, começou a demorar mais que o normal. Com isso logo veio a pergunta, porque não fazer um commit a cada comando? Considerando o contexto da rotina, o commit a cada comando não seria possível, exceto em um update. Mas como fazer um commit isolado no meio da transação? A resposta é pragma autonomous_transaction;
Funciona apenas dentro de uma procedure, você cria uma procedure e coloca a declaração pragma autonomous_transaction; pronto essa procedure será considerada uma transação a parte, execute o seu comando e execute o commit.
PS: Funciona desde o Oracle 8i
Exemplo
Begin
Insert ......
Delete ......
Chamada da procedure com a transação autônima.......esse pedaço terá um commit a parte
Etc.......
Commit;
End;