Propósito

✔ Programação GLOBAL® - Quaisquer soluções e/ou desenvolvimento de aplicações pessoais, ou da empresa, que não constem neste Blog devem ser tratados como consultoria freelance. Queiram contatar-nos: brazilsalesforceeffectiveness@gmail.com | ESTE BLOG NÃO SE RESPONSABILIZA POR QUAISQUER DANOS PROVENIENTES DO USO DOS CÓDIGOS AQUI POSTADOS EM APLICAÇÕES PESSOAIS OU DE TERCEIROS.

.: Vitrine

Carregando artigos...

Views

Mostrando postagens com marcador memory. Mostrar todas as postagens
Mostrando postagens com marcador memory. Mostrar todas as postagens

VBA Advanced Excel - Evitando que aplicações Excel fiquem carregados no memória.


Caso não nos resguardemos bem ao escrevermos as nossas aplicações com o MS Excel, podemos incorrer no erro, muito comum, de permitir que processos fiquem soltos e perdidos na memória RAM do nosso sistema operacional.

Ao construirmos aplicações que acessam e manipulam objetos e recursos de outro aplicativos, dependendo do nosso nível de conhecimento, podemos tornar tais automações tecnicamente complexas, pois às vezes envolverão diversas interfaces entre a aplicação cliente, e a aplicação servidor, além do próprio sistema operacional.

Já estamos bem acostumados a usar o MS Office como servidor de automações. E ele é excelente nisso, pois além de oferecer recursos avançados como editor de textos, planilha eletrônica, modelos gráficos, apresentações, etc... que complementam vários tipos de soluções, ainda consegue encapsular complexos aplicativos de automação, tornando os processos mais simples para nós, desenvolvedores. E um alívio e tanto para os usuários que não precisam dedicar centenas de horas no ano para processos repetitivos, que imploram por erros.

Uma vez que praticamente todos os  recursos estejam disponíveis programaticamente não há simplesmente como comparar MS Office a outros pacotes concorrentes. Encontramos sim, um enorme abismo que o diferencia e distancia das demais suites. É nítido o que a programação lhe agrega, acrescentando-lhe ainda mais facilidade e valor. 

Também não é por acaso, que de todos os softwares do pacote MS Office, o MS Excel seja o mais usado como servidor de automação, especialmente por ser um produto versátil (repositório de dados, motor de cálculos, gerador de gráficos, Dashboards e Scorecards, etc...), usado de ponta a ponta no mercado, em praticamente todos os modelos de negócio.

Cuidado...
A automação é fácil de ser implementada, mas, precisa receber especial atenção ao fato de que ao abrirmos um aplicativo, o mesmo deve ser fechado a posteriori. Neste artigo, que é aplicável em qualquer outro módulo da suite, usaremos o MS Excel:

Manual
A automação funcionará de modo similar a quando um usuário aciona uma aplicação MS Excel, abre uma pasta de trabalho, escolhe uma planilha, e começa a ler e preencher as  células. Com estes passos simples e muito comuns um processo do MS Excel é iniciado no Windows e, quando um usuário fecha-o, o processo é finalizado.

Automatizado
Num cenário automatizado porém, é muito comum o aplicativo servidor ser executado nos bastidores, de modo invisível ao usuário que, na maioria das vezes, sequer imagina que o MS Excel (ou seja lá qual for o aplicativo) está sendo executado. Como o usuário não tem a janela do MS Excel ativa para poder fechar, quem deve fazer isto é a própria aplicação que o abriu, caso contrário o processo ficará pendurado no Windows. Mas há um cenário ainda mais perturbador para o Cliente e conseqüentemente para o desenvolvedor: Deixar a pasta de trabalho do usuário bloqueada de forma que não consiga acessá-la nem abrindo o MS Excel manualmente, nem por outro processo de automação.

Este é um erro muito comum nos fóruns mundo a fora: "Minha planilha [neste caso] está travada, não consigo editar nada!". O usuário diz que fechou todos os programas (e de fato fechou), abriu seu arquivo do MS Excel e recebeu esta mensagem de erro.

Mas, quando solicitamos que ele abra o seu WTM (Windows Task Manager) indo para a guia processos, e classificando-a por nome, estes invariavelmente encontram listadas repetidas vezes o arquivo "EXCEL.EXE". Os processos são finalizados e, momentâneamente, o problema está resolvido. 

Inline image 3

Mais tarde, porém, o problema volta a se repetir. Por quê? Algum aplicativo que usa o MS Excel como servidor de automação falha em fechá-lo 'completamente'. Geralmente ocorre algum erro em tempo de execução no código depois que a aplicação foi instanciada, deixando-a pendurada na memória.

Como evitar...
Antes que o cenário constrangedor descrito acima ocorra trazendo vitupério para todos os desenvolvedores da plataforma VBA, pois dirão: "O VBA não é estável!". 

Recomendo uma das seguintes simples práticas, por prioridade:
a) DEIXE A APLICAÇÃO VISÍVEL: Se o objetivo da automação for preparar um arquivo exibindo o resultado final ao usuário, nada mais óbvio que torná-lo visível, certo? Mas, algumas vezes o desenvolvedor não faz isto: ele abre o MS Excel, executa as rotinas de preenchimento, salva, fecha e, por fim, executa o comando Shell para abrir o arquivo em uma nova instância do MS Excel.

O recomendado é deixar a instância visível, fazendo isso logo no início do código. Deste modo, caso ocorra algum erro durante a execução do código, o processo não ficará perdido no Windows, pois o usuário terá domínio da janela.

Sub MySub1()
Dim xlApp As Excel.Application
Dim xlWkb As Excel.Workbook
On Error GoTo ErrHandler
"Instancia o Excel
Set xlApp = New Excel.Application
"Deixa o Excel visível para o usuário
xlApp.Visible = True
"Seu código aqui...
ExitHere:
Exit Sub
ErrHandler:
MsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"
Resume ExitHere
End Sub

b) CONTROLE A APLICAÇÃO E FAÇA A FINALIZAÇÃO DO TRATAMENTO DO ERRO: Também é comum alguns colocarem um comando para finalizar o MS Excel (tal como Quit) no tratamento de erro. Porém, se o erro ocorrer por outro motivo que não a automação e o MS Excel não estiver instanciado no momento, este tratamento gerará outro erro: Object variable or With block variable not set. Para que esse erro não ocorra, o mais correto é, antes de fazer o Quit, verificar se o MS Excel foi instanciado:

Sub MySub2()
Dim xlApp As Excel.Application
Dim xlWkb As Excel.Workbook
Dim blnIsOpen As Boolean
On Error GoTo ErrHandler
"Instancia o Excel
Set xlApp = New Excel.Application
blnIsOpen = True
"Seu código aqui...
"Finaliza a aplicação
xlApp.Quit
blnIsOpen = False
ExitHere:
Exit Sub
ErrHandler:
"Verifica se o Excel está instanciado
If blnIsOpen = True Then
    xlApp.Quit
End If
MsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"
Resume ExitHere
End Sub
Checando...
Com o código abaixo poderá testar se uma instância do MS Excel está aberta e caso esteja, poderá evocá-la:

Dim ExcelApplication As Object
   Dim TimeoutTime As Long

   On Error Resume Next
   Set ExcelApplication = GetObject(, "Excel.Application")
   On Error GoTo 0

   If ExcelApplication Is Nothing Then
       Shell "Excel.exe"

       Let TimeoutTime = Timer + 5

       On Error Resume Next

       Do
           DoEvents
           Err.Reset
           Set ExcelApplication = GetObject(, "Excel.Application")
       Loop Until Not ExcelApplication Is Nothing Or Timer > TimeoutTime

       On Error GoTo 0
   End If

   If ExcelApplication Is Nothing Then
       MsgBox "Unable to launch Excel."
   Else
       ' Do something with the Excel instance...
   End If



Inspired in

Luiz Cláudio C Rocha




Tags: VBA, Office, automation, Excel, Clean, memory,automação, Advanced


VBA Excel - Funções com informações de Memória não estão disponíveis na versão MS Excel 2007 - Memory functions unavailable in Excel 2007





Nas anteriores versões do MS Excel as funções abaixo estavam disponíveis:




Application.MemoryFree 
Application.MemoryTotal 
Application.MemoryUsed 



Mas na versão do MS Excel 2007 elas disapareceram. Mas nem tudo está perdido, a função GlobalMemoryStatus pode ser usada, e está disponível como função API do Windows:




Iniciar o Microsoft Excel e crie uma nova pasta de trabalho.

No menu Ferramentas , aponte para macro e em seguida, clique em Editor do Visual Basic (ou pressione ALT+F11).

No menu Inserir , clique em módulo .

Na folha de módulo, digite o seguinte código:  


Option Explicit
Type SYSTEM_INFO
    dwOemID As Long
    dwPageSize As Long
    lpMinimumApplicationAddress As Long
    lpMaximumApplicationAddress As Long
    dwActiveProcessorMask As Long
    dwNumberOrfProcessors As Long
    dwProcessorType As Long
    dwAllocationGranularity As Long
    dwReserved As Long
End Type

Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type

Type MEMORYSTATUS
    dwLength As Long
    dwMemoryLoad As Long
    dwTotalPhys As Long
    dwAvailPhys As Long
    dwTotalPageFile As Long
    dwAvailPageFile As Long
    dwTotalVirtual As Long
    dwAvailVirtual As Long
End Type

'The following three Declare lines must be each entered on a single
'line.

Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
             (LpVersionInformation As OSVERSIONINFO) As Long
Declare Sub GlobalMemoryStatus Lib "kernel32" (lpBuffer As _
            MEMORYSTATUS)
Declare Sub GetSystemInfo Lib "kernel32" (lpSystemInfo As _
              SYSTEM_INFO)

Public Const PROCESSOR_INTEL_386 = 386
Public Const PROCESSOR_INTEL_486 = 486
Public Const PROCESSOR_INTEL_PENTIUM = 586
Public Const PROCESSOR_MIPS_R4000 = 4000
Public Const PROCESSOR_ALPHA_21064 = 21064

Sub SystemInformation()
Dim msg As String         ' Status information.
Dim NewLine As String     ' New-line.
Dim ret As Integer        ' OS Information
Dim ver_major As Integer  ' OS Version
Dim ver_minor As Integer  ' Minor Os Version
Dim Build As Long         ' OS Build

      NewLine = Chr(13) + Chr(10)  ' New-line.
      ' Get operating system and version.
      Dim verinfo As OSVERSIONINFO
      verinfo.dwOSVersionInfoSize = Len(verinfo)
      ret = GetVersionEx(verinfo)
      If ret = 0 Then
          MsgBox "Error Getting Version Information"
          End
      End If

      Select Case verinfo.dwPlatformId
          Case 0
              msg = msg + "Windows 32s "
          Case 1
              msg = msg + "Windows 95/98 "
          Case 2
              msg = msg + "Windows NT/2000 "
      End Select

      ver_major = verinfo.dwMajorVersion
      ver_minor = verinfo.dwMinorVersion
      Build = verinfo.dwBuildNumber
      msg = msg & ver_major & "." & ver_minor
      msg = msg & " (Build " & Build & ")" & NewLine & NewLine

      ' Get CPU type and operating mode.
      Dim sysinfo As SYSTEM_INFO
      GetSystemInfo sysinfo
      msg = msg + "CPU: "
      Select Case sysinfo.dwProcessorType
          Case PROCESSOR_INTEL_386
              msg = msg + "Intel 386" + NewLine
          Case PROCESSOR_INTEL_486
              msg = msg + "Intel 486" + NewLine
          Case PROCESSOR_INTEL_PENTIUM
              msg = msg + "Intel Pentium" + NewLine
          Case PROCESSOR_MIPS_R4000
              msg = msg + "MIPS R4000" + NewLine
          Case PROCESSOR_ALPHA_21064
              msg = msg + "DEC Alpha 21064" + NewLine
          Case Else
              msg = msg + "(unknown)" + NewLine
      End Select

      msg = msg + NewLine

      ' Get free memory.
      Dim memsts As MEMORYSTATUS
      Dim memory As Long
      GlobalMemoryStatus memsts
      memory = memsts.dwTotalPhys
      msg = msg + "Total Physical Memory: "
      msg = msg + Format(memory \ 1024, "###,###,###") + "K" + NewLine
      memory = memsts.dwAvailPhys
      msg = msg + "Available Physical Memory: "
      msg = msg + Format(memory \ 1024, "###,###,###") + "K" + NewLine
      memory = memsts.dwTotalVirtual
      msg = msg + "Total Virtual Memory: "
      msg = msg + Format(memory \ 1024, "###,###,###") + "K" + NewLine
      memory = memsts.dwAvailVirtual
      msg = msg + "Available Virtual Memory: "
      msg = msg + Format(memory \ 1024, "###,###,###") + "K" + NewLine

      MsgBox msg, vbOKOnly, "System Info"
End Sub

No menu Ferramentas , aponte para macro e, em seguida, clique em macros .

Clique em SystemInformation e, em seguida, clique em Executar .






Reference::Gerrit-Jan Linker



212536 OFF2000: Como executar o código de exemplo de artigos da Knowledge Base



161151 COMO: Obter informações de status do Windows por meio de chamadas de API



189249 COMO: Determinar qual versão do Windows de 32 bits está sendo usado






Tags: VBA, Excel, Memory, memória,  Excel 2007, API, Windows, 




Inline image 1

VBA Tip - Como utilizar a memória RAM - Using Clipboard, RAM Memory

Pois é, 
Todos usamos muito a famosa funcionalidade CTRL + C e CTRL + V. Sim o copy/paste é muito útil e porque não dizer, indispensável. Mas como podemos implementar essa funcionalidade dentro das nossas aplicações MS Office?

How to Use the Office Clipboard in VBA
How to Copy From the Clipboard in Excel Using VBA
How to Cut & Paste From the Clipboard in Excel VBA

0338_pix_gemeos_copy_paste.jpg

Em que momento desejarei utilizar essa funcionalidade nas minhas aplicações? Através do VBA, é possível, por exemplo,  recuperarmos quaisquer informações que estiverem na Área de Transferência, utilizando-as em nossas aplicações, ou podemos fazer o caminho inverso e disponibilizar o resultado de certo processamento para a área de transferência.








Sub PutInRAM ()     Dim nOBJ As MSForms.DataObject     Set dtOBJ = New MSForms.DataObject          Dim n As String

Let n = "Bernardes"

    dtOBJ.SetText s
     dtOBJ.PutInClipboard 

End Sub

Sub GetInRam ()     Dim dtOBJ As MSForms.DataObject     Dim n As String          Set dtOBJ = New MSForms.DataObject          dtOBJ.GetFromClipboard          Let n = dtOBJ.GetText          MsgBox n 

End Sub
 

' Compatibilizando as versões do MS Office

#If VBA7 Then

    Public Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long

    Public Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long

    Public Declare PtrSafe Function CloseClipboard Lib "user32" () As Long

#Else

    Public Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long

    Public Declare Function EmptyClipboard Lib "user32" () As Long

    Public Declare Function CloseClipboard Lib "user32" () As Long

#End If



Sub EmptyInRAM()

    OpenClipboard (0&)



    EmptyClipboard



    CloseClipboard

End Sub



Referência: Ambiente Office
                    CPerson



Tags: Bernardes, MS, Microsoft, Office, VBA, TIP, Clipboard, RAM, memory, memória, RAM, copy/paste















André Luiz Bernardes
A&A® - Work smart, not hard.
Skype: inanyplace 


diHITT - Notícias