Академический Документы
Профессиональный Документы
Культура Документы
Vba Unicamp
Vba Unicamp
Projeto Supervisionado II
%luna& atiana Suem' (tsu)a (rientador& Prof* +r* %ntonio Carlos Moretti , +pto* de matemtica aplicada - de .ul/o de 0120
3ndice
(!jetivo 4444444444444444444444444444444444444444444444444444444444444444 444444444444444444444444444444444444444444444444444444444444444444 444444444444444444444444444444444415 44 Introdu Introduo 4444444444444444444444444444444444444444444444444444444444444444 444444444444444444444444444444444444444444444444444444444444444416 44444444444444444444444444444444 2* ( 7ue 8 #$%9 1#$%9 0* (!jetos do E:cel 4444444444444444444444444444444444444444444444444444444 1; 5* Conceitos !sicos 444444444444444444444444444444444444444444444444444444 4444444444444444444444444444444444444444444444444444441< 4444444444444444444444 5*2 Su!-rotinas 1< 5*0 #ariveis e Constantes 1< 5*5 Cai:as de Entrada e Mensa"ens 21 5*6 Comentrios, Concatenao de Strin" e Pular =in/as 22 5*- #etores 20 5*; Propriedade offset 25 5*< Propriedade End 26 5*> Constru?es com @it/ 26 5*A Estruturas de Condi?es 25*21 Estruturas de =oopin"s 26* @or)!oo)s 4444444444444444444444444444444444444444444444444444444444444 44444444444444444444444444444444444444444444444444444444444442; 44444444444444444444444444444 -* Event Bandler 4444444444444444444444444444444444444444444444444444444444 44444444444444444444444444444444444444444444444444444444442; 44444444444444444444444444 ;* User Corms 4444444444444444444444444444444444444444444444444444444444444 2; ;*2 Parte Drfica 2< ;*0 Event Bandler para User Corms 2> <* C/amando o Solver pelo #$% 4444444444444444444444444444444444444444444 2A >* Importando +ados do %ccess 4444444444444444444444444444444444444444444 00 >*2 Eelational +ata!ases 00 >*0 %+( 05 A* ( Pro!lema de transporte 4444444444444444444444444444444444444444444444 0A*2 Pr8-Modela"em 0A*0 E:ecuo da %plicao 0; 21* % Pro"rama Pro"ramao em #$% 4444444444444444444444444444444444444444444444 0A 21*2 Confi"ura?es iniciais 0A 21*0 Criando o m:imo no modo "rfico 51 21*5 .anela /is@or)!oo) 52 21*6 Inserindo Cormulrios Cormulrios e Event Bandlers 4444444444444444444444444444444 50 21*- Constru Construo de Su!rotinas 44444444444444444444444444444444444444444444 56 Concluso 4444444444444444444444444444444444444444444444444444444444444444 4444444444444444444444444444444444444444444444444444444444444444644444444444444444444444444444444 EeferFncias EeferFncias 444444444444444444444444444444444444444444444444444444444444444 4444444444444444444444444444444444444444444444444444444444444446; 4444444444444444444444444444444 $i!lio"rafia $i!lio"rafia44444444444444444444444444444444 afia 4444444444444444444444444444444444444444444444444444444444444444 44444444444444444444444444444444444444444444444444444444444444446< 44444444444444444444444444444444
(!jetivo
( presente projeto tem como o!jetivo servir de um !reve tutorial para a7ueles interessados em utiliGar a plataforma Microsoft E:cel e a lin"ua"em, #isual $asic for %pplications H#$%I como ferramentas para a modela"em de pro!lemas de otimiGao* Procura-se com este tutorial poder e:emplificar a funcionalidade dessa ferramenta para modelos de suporte de deciso*
Introduo
( propJsito deste tra!al/o no 8 ensinar em detal/es a lin"ua"em #$%, nem desenvolver a modela"em de um novo pro!lema, mas sim ser um "uia para iniciar a construo de modelos faGendo uso dessa lin"ua"em e e:plorando seus diferenciais e praticidades* %trav8s do #$%, modelos relativamente comple:os podem ser acessveis a 7ual7uer usurio de E:cel, sendo apresentados de forma ami"vel atrav8s de simplificadas telas de entrada de dados e claros relatJrios finais* % primeira parte deste tutorial consiste em uma !reve e:plicao das principais ferramentas, conceitos e comandos utiliGados nos modelos* Em se"uida 8 desenvolvido um modelo de transporte clssico, aplicando o 7ue foi mostrado primeiramente* Pr8-re7uisitos& Este tutorial assume 7ue os leitores estejam familiariGados com modelos clssicos de pes7uisa operacional, 7ue ten/am e:periFncia com al"uma lin"ua"em de pro"ramao e sejam usurios da interface do E:cel* (!servao& % construo deste tutorial foi !aseada na verso do E:cel 011<, contudo para as outras vers?es / poucas mudanas na lin"ua"em #$% em si*
2* ( 7ue 8 #$%9
#$% H#isual $asic for %pplicationsI 8 uma lin"ua"em de pro"ramao com elementos tpicos, como loopin"s, constru?es de if-t/en-else, vetores, fun?es, etc* ( Kfor applicationsL do nome #$%, si"nifica 7ue 7ual7uer softMare de aplicao, como E:cel, %ccess, @ord, ou at8 mesmo pacotes 7ue no sejam da Microsoft, podem ser manipulados pro"ramando-se em #$%* % diferena !sica entre eles consiste em seus o!jetos especficos* Por e:emplo, al"uns o!jetos do E:cel so c8lulas e planil/as* . o @ord possui par"rafos, e o PoMerPoint Slides* odos 7ue possuem o Microsoft (ffice instalado no computador, podem utiliGar o #$%* No E:cel, o #isual $asic Editor H#$EI, 7ue 8 a rea onde 8 feita a pro"ramao, pode ser acessado pressionando-se %ltOC22* %ltOC22
0* (!jetos do E:cel
Para e:emplificar um o!jeto do E:cel, considere uma Pnica c8lula* Essa c8lula 8 um o!jeto do tipo Ean"e, Ean"e 7ue tem propriedades, como a propriedade #alue Hte:to ou nPmero di"itado na c8lulaI* Esse o!jeto tem tam!8m m8todos, por e:emplo, o m8todo Cop' Hfuno 7ue copia o Ean"eI, , 7ue possui ar"umentos como o +estination H=ocal aonde ser colado o 7ue foi copiadoI* %l"uns o!jetos do E:cel possuem eventos* Por e:emplo, o o!jeto @or)!oo) possui o evento (pen* (pen am!8m e:istem as cole?es de o!jetos 7ue similarmente aos o!jetos, possuem m8todos e propriedades, por8m estes nem sempre so os mesmos dos o!jetos 7ue contFm* Cole?es so diferenciadas por serem nomeadas no plural* Por e:emplo, a coleo de o!jetos @or)s/eets, @or)s/eets, 8 a coleo de todas as planil/as do ar7uivo, e cada planil/a 8 um o!jeto do tipo @or)s/eet* @or)s/eet Uma Jtima ferramenta para verificar todos os o!jetos, suas propriedades, m8todos, eventos 8 o Pes7uisador de o!jeto 7ue pode ser acessado dentro do editor #$E em E:i!ir -Q Pes7uisador Pes7uisador de o!jeto* o!jeto (utra ferramenta de ajuda 7ue sempre deve ser utiliGada 8 o Intellisense* Intellisense %o di"itar em um MJdulo, o nome de um o!jeto, se"uido de um ponto, todas as propriedades e m8todos desse o!jeto sero listados, veja fi"ura 0*2* Essa ferrmamenta tam!8m lista todos os ar"umentos de um m8todo ao di"itar o m8todo e pressionar a tecla de espao, como mostra a fi"ura 0*0* Rual7uer ar"umento e:i!ido em c/aves 8 opcional, os outros so o!ri"atJrios*
Ci"ura 0*0
Ci"ura 0*2
5* Conceitos !sicos
Esse captulo pretende mostrar de forma !reve como 8 a sinta:e dos comandos necessrios para o entendimento da modela"em 7ue ser feita no captulo HI*
5*2 Su!Su!-rotinas
Uma modela"em "eralmente possui muitas tarefas, o 7ue em #$% 8 c/amado de su!su!-rotina, macro ou simplesmente su!* Uma su! "eralmente 8 um "rupo de cJdi"os di"itados em um MJdulo, MJdulo 7ue e:ecutam uma determinada tarefa* Para inserir um mJdulo entre no editor #$E em HInserir -Q MJduloI* MJduloI Uma su!-rotina tem um nome e pode ou no ter ar"umentos como em& Sub Teste(Name As String, Number As Integer) End Sub Para e:emplificar, esta su!-rotina pode ser c/amada da se"uinte forma& Sub Chamar() Dim Nome As Sting, Numero As Integer ... Call Teste(Nome, Num) End Sub %o c/amar uma su!-rotina com ar"umentos, eles devem coincidir em tipo, ordem e nPmero, mas no precisam ter os mesmo nomes*
E:emplo& &
$oolean Hassume os valores rue ou CalseIS Sin"le Hpara nPmeros decimaisIS +ou!le Hpara nPmeros decimais com mais casasIS Currenc' Hpara valores monetriosIS #ariant Hpode ser de 7ual7uer tipo a ser decidido pelo #$%I*
Sub Var() Dim j As Integer Dim name As String Dim Test As Boolean End Sub (u, simplificando& Sub Var() Dim j As Integer, name As String, Test As Boolean End Sub (ption E:plicit& UtiliGando o Comando (ption E:plicit no incio de um mJdulo foramos a declarao das variveis, antes de 7ual7uer uso dela* Se al"uma no for declarada, uma mensa"em de erro aparecer na tela*
(!jetos&
Um o!jeto tam!8m 8 uma varivel e deve ser declarado como em& Dim celula As Range
CaGendo isso, podemos atri!uir um ran"e a KcelulaL e tra!al/ar com essa varivel* E:emplo& & Dim celula As Range Set celula = ActiveWorkbook.Worksheets(Data).Range(Nomes) celula.Font.Size=12
( comando Set sempre 8 usado para atri!uir valor ou definir uma varivel do tipo (!jeto, mas nunca 8 usado para outros tipos de variveis* Por e:emplo, para uma varivel do tipo KInte"erL, atri!umos valor desta forma& Dim j As Integer j=20
+eclarando +eclarando variveis pP!licas Se o pro"ramador declarar uma varivel dentro de certa su!-rotina, esta varivel ser local, ou seja, ser acessada apenas por essa su!-rotina* Caso deseje-se utiliGar uma varivel em mais de uma su!-rotina do mJdulo, 8 necessrio declarar a varivel da forma como foi e:plicado, por8m no incio do mJdulo, antes de 7ual7uer su!rotina* %"ora, se o modelo tiver mais de um mJdulo, ou, por e:emplo, um Event Bandler para UserCorms, e deseja-se 7ue certa varivel seja visvel para todos os mJdulos e Event Bandlers, ento declara-se a varivel tam!8m no incio do mJdulo mas da se"uinte forma& Public variavel As Integer Pelo padro do #$%, su!-rotinas so pP!licas, ou seja, podem ser c/amadas por 7ual7uer outra su!-rotina do projeto* Para 7ue essa su!-rotina sJ possa ser c/amada dentro de um mJdulo, a declaramos desta forma& Private Sub Test()
Ci"ura 5*2
( Ms"$o: rece!e pelo menos um ar"umento, a mensa"em 7ue deseja-se informar* +ois ar"umentos opcionais so& um !oto de indicao e o ttulo da cai:a* E:emplo& & MsgBox A cor laranja., vbInformation, Cor escolhida
10
Ci"ura 5*0
Comentrios
Coloca-se o caracter K T K antes da lin/a a ser comentada* E:emplo& Esta linha um comentrio
Pular lin/as
Ruando uma lin/a de cJdi"o e:ceder o taman/o da tela, 8 possvel cort-la e continuar na prJ:ima lin/a atrav8s dos caracteres Hespao O underlineI* Por e:emplo&
MsgBox InputBox(Digite um nmero a ser exibido na caixa de mensagem, _ Entrada de dados), vbInformation, Nmero digitado
11
Concatenao de Strin"s
Ruando 7uereremos escrever uma mensa"em com partes literais e outras variveis, por e:emplo, o valor de uma varivel, devemos concatenar uma strin", separando as partes com o caractere KU UL& & E:emplo& & Dim product As Integer product=12 MsgBox O nmero do produto & product & .
5*- #etores
+eclara-se um vetor desta forma& Dim vetor(100) As String Ruando no se sa!e de antemo o taman/o do vetor, o declaramos desta forma& Dim vetor() As String Se o taman/o do vetor for con/ecido ao lon"o da e:ecuo do pro"rama, devese redimension-lo para o armaGenamento necessrio de memJria* Para isso, utiliGase a sentena Eedim& Eedim& numero= InputBox(Quantos ndices o vetor ter?) Redim vetor(Numero) Pode-se usar a declarao Eedim toda veG 7ue se deseja mudar a dimenso de um vetor* Por8m ao faGer isso, todo o contePdo do vetor ser apa"ado* Para 7ue isso no ocorra, 8 necessrio utiliGar a declarao Preserve& Preserve numero=numero+1 Redim Preserve vetor(1 to Numero) 12
Pode-se tam!8m especificar um "rupo de c8lulas, como& With Range(A1) Range(.Offset(1,1), .Offset(2,2)).Select End With
13
Ci"ura 5*6
14
Estrutura IC
Estrutura Case
Select Case someVariable Case value1 Statements1 Case value2 Statements2 [Case Else OtherStatements] End Select
If condition1 Then Statements1 [ElseIf condition2 Then Statements2 Else OtherStatements] End If
Estrutura Cor
15
6* @or)!oo)s
Um @or)!oo) 8 !asicamente o ar7uivo em E:cel*, ou seja, toda a rea de tra!al/o* Uma coleo @or)!oo)s 8 a coleo de todos os Mor)!oo)s a!ertos* Rual7uer mem!ro dessa coleo pode ser especificado por um nome como @or)!oo)sHK%r7uivo :LI* Cada Mor)!oo) individual possui as cole?es @or)s/eets e C/arts, por e:emplo* (utro conceito 8 o de 7ue @or)!oo)s, @or)s/eets e C/arts tam!8m so o!jetos, e possuem m8todos e propriedades* Uma importante propriedade 8 o Count, Count 7ue conta o nPmero de Mor)s/eets, Mor)!oo)s ou c/artsS e um m8todo importante 8 o %dd, %dd 7ue adiciona uma nova coleo dentre essas*
-* Event Bandler
Um Event Bandler 8 uma su!-rotina 7ue 8 e:ecutada sempre 7ue certo evento ocorre* Um dos mais importantes 8 o se"uinte&
;* User Corms
User Corms so janelas para a entrada de dados do usurio* Para constru-los 8 necessrio ela!orar a parte "rfica com a funcionalidade desejada e de forma a ser atrativa e prtica para o usurio* %l8m disso, 8 necessrio implementar a parte da pro"ramao 7ue e:ecuta as tarefas determinadas pelo usurio*
16
Ci"ura ;*2
%l8m das ferramentas e:i!idas na cai:a de ferramentas, outras podem ser adicionadas clicando com o !oto direito na cai:a e em controles adicionais* odas as ferramentas da cai:a de ferramentas so !astante intuitivas de serem usadas, por8m para e:plica?es mais detal/adas consulte a !i!lioteca MSCorms no Pes7uisador de (!jetos* % janela de propriedades mostra as propriedades de cada controle se este estiver selecionado* +uas propriedades importantes so Name e Caption* % propriedade Name 8 usada como referFncia para um UserCorm e a Caption confi"ura os te:tos e:i!idos na tela* Essas propriedades, assim como todas as outras podem ser alteradas diretamente na janela de propriedades* 17
Para visualiGar o resultado final do Userform cli7ue em E:ecutar-QE:ecutar Su!WuserCorm ou a tecla C-*
Ci"ura ;*0
Ci"ura ;*5
+entro de cada su!-rotina 8 necessrio escrever o cJdi"o para a e:ecuo de determinada tarefa* % id8ia de Event Bandler para User Corm 8 decidir 7ual tarefa ser e:ecutada como resposta a certo evento*
18
Ci"ura <*2
19
Ci"ura <*0
odas as fun?es do Solver comeam com a palavra Solver* Solver %s mais usadas so SolverEeset, Solver(), Solver%dd, Solver(ptions e SolverSolver, 7ue sero e:plicadas a!ai:o* Para visualiGar a lista completa, entre no Pes7uisador de (!jeto, selecione a !i!lioteca Solver, e ento, o "rupo #$%4Cunctions*
Cun?es& -SolverEeset %pa"a todas as confi"ura?es anteriores para um novo clculo* -Solver(Z Essa funo realiGa trFs tarefas& H2I H0I H5I E:emplo& SolverOK SetCell:=Range(Profit), MaxMinVal=:1, ByChange:=Range(Quantities) ( ar"umento Ma:Min#al, rece!e 2 para pro!lemas de ma:imiGao e 0 de minimiGao* -Solver%dd Essa funo adiciona uma nova restrio cada veG 7ue 8 c/amada e tem trFs ar"umentos* 20 Identifica a c8lula 7ue cont8m a funo o!jetivo Especifica se o pro!lema 8 de ma:imiGao ou minimiGao Identifica as c8lulas com as variveis de deciso*
( ar"umento central 8 um ndice de relao 7ue tem valores 2 para K[\ [\L, [\ 0 para K\ \L, 5 para KQ\ Q\L, inteiroL !inrioL* Q\ 6 para Kinteiro inteiro e - para K!inrio !inrio (s outros ar"umentos sero as c8lulas relacionadas* Para as desi"ualdades, o primeiro ar"umento 8 sempre especificado como um Ean"e, e o terceiro como uma strin" ou nPmero* E:emplo& SolverAdd CellRef:=Range(Used), Relation:=1, FormulaText:=0 -Solver(p Solver(ptions Solver(ptions Essa funo permite escol/er 7ual7uer uma das op?es da janela de op?es do Solver&
Ci"ura <*5
Pelo fato de todas as op?es no serem o!ri"atJrias, !asta listar somente os ar"umentos desejados, separando-os por vr"ula* Uma dica 8 utiliGar o Intelicensse di"itando Solver(ptions e espao para ver os nomes dos vrios ar"umentos possveis*
Ci"ura <*6
21
-SolverSolve Essa funo 8 e7uivalente a clicar no !oto KEesolverL na usual janela do Solver para e:ecutar a otimiGao* SolverSolve retorna um valor inteiro, sendo 1 sinaliGando 7ue o Solver foi e:ecutado com sucesso, 6 para no conver"Fncia e - para soluo no factvel* ] conveniente usar o ar"umento UserCinis/&\ rue, para 7ue a janela de resultados padro no aparea ao final, evitando interrup?es ao lon"o da e:ecuo* E:emplo& Dim result As Integer result = SolverSolve(UserFinish:=True) If result = 5 Then MsgBox No existe nenhuma soluo factvel. End if
% lin"ua"em Structured Ruer' =an"ua"e HSR=I foi desenvolvida para retornar dados de !ancos de dados relacionados* Ele se aplica de certa forma V todos os sistemas de !ancos de dados como o %ccess, SR= Server, (racle, etc* Por8m esta lin"ua"em no 8 perce!ida ao tra!al/ar com o %ccess, pois este possui uma interface ami"vel ao usurio, 7ue esconde as sentenas da lin"ua"em* Para desenvolver a modela"em sero utiliGados !ancos de dados do %ccess e portanto, a lin"ua"em SR= dentro do #$%, por8m de forma !em simples* Para informa?es mais detal/adas a referFncia X5Y*
>*0 %+(
% tecnolo"ia %+( permite ao desenvolvedor escrever cJdi"os relativamente simples para !uscar um !anco de dados e:ternos* Para utiliGar o %+(, 8 necessrio inserir uma referFncia a ele* No editor #$E, entre em CerramentasCerramentas-QEeferFncias, QEeferFncias procure a !i!lioteca Microsoft %ctive^ +ata (!jects 0*: e cli7ue em (Z* Essa referFncia no ir aparecer no Project E:plorer como o Solver, pois nesse campo sJ aparecem items no desenvolvidos pela Microsoft* Para se referir V um o!jeto do %+(, use o prefi:o %+(+$, %+(+$ como em %+(+$*Connection* %ssim 7ue di"itar %+(+$* e um espao, uma ajuda so!re a !i!lioteca ser dada pelo Intellisense* Pode-se consultar ajuda tam!8m pelo Pes7uisador de (!jetos*
%l"umas tarefas&
%!rir uma cone:o com o !anco de dados&
Primeiramente, declarar uma varivel no formato de um o!jeto do tipo Connection, especificar aonde o ar7uivo est, e 7ual seu provedor, no caso do %ccess o provedor 8 Microsof .et 6*1 (=E +$ Provider* Ento, a!rir o ar7uivo e fec/ar a cone:o* Se"ue um e:emplo&
23
Dim cn as New ADOBD.Connection Esse cdigo procura o arquivo Arquivo.mdb na pasta de trabalho atual em que o arquivo de Excel se encontra. With cn .ConnectionString=Data Source & ThisWorkbook.Path & \Arquivo.mdb .Provider = Microsof Jet 4.0 OLE DB Provider .Open End With cn.Close
%!rir um Ee"istro
Um re"istro 8 um !anco de dados temporrio 7ue fica armaGenado na memJria* Para acess-lo, declara-se uma varivel no formato de um o!jeto do tipo Eecordset, depois utiliGando uma varivel do tipo strin" 7ue cont8m declara?es em SR=, a!rimos o re"istro com o m8todo (pen* (s dois primeiros ar"umentos deste m8todo so uma SR= strin" e o o!jeto de cone:o 7ue j foi a!erto* Se"ue o cJdi"o do procedimento& rs as New ADOBD.Recordset Abrir o registro rs.Open SQL, cn Fecha o registro rs.Close
( %+( pode ser usado para a!rir outros tipos de !ancos de dados sem ser no formato %ccess, como por e:emplo, !ancos de dados armaGenados em servidores* % Pnica diferena nos cJdi"os acima para a!rir estes !ancos so nas propriedades ConnectionStrin" e Provider* Procurar Procurar al"uma informao no !anco de dados&
Este cdigo executa as declaraes em cada linha do registro at encontrar o fim do arquivo, (EOF significa end of file). With rs Do Until .EOF Delacraes .MoveNext Loop End With
24
%l"uns comandos Pteis em SR=& SE=EC & lista os campos 7ue cont8m os dados desejados* CE(M& especifica a ta!ela ou ta!elas 7ue cont8m estes dados* @BEEE& =ista um crit8rio especfico* DE(UP $_& $_& permite o a"rupamentos de al"uns dados, por e:emplo o total de carros de certa marca* Neste caso o comando seria DE(UP $_ marca* (E+EE $_& Permite ordenar o !anco desejado*
A* Implementando a Modela"em
A*2 Pr8Pr8-Modela"em
%ntes de iniciar uma modela"em em #$%, 8 Ptil 7ue o pro"ramador pense nos se"uintes tJpicos& 2-Como os dados sero inseridos 0-Como criar o modelo com os dados de entrada e o!ter a resoluo do pro!lema 5-Como os resultados sero e:i!idos Para solucionar o se"undo tJpico 8 necessrio con/ecimento matemtico de modela"em, e isso no ser tratado neste tutorial* Para mais informa?es so!re a modela"em a ser desenvolvida consulte a referFncia X0Y* Como resposta do primeiro tJpico, o pro"ramador pode escol/er a entrada de dados por cai:as de dilo"o, construindo User Corms* Mas como na maioria das veGes e:iste uma "rande 7uantidade de dados a ser tra!al/ada, essa opo torna-se invivel* Muitas veGes os dados esto em outros ar7uivos do E:cel, ou em !ancos de dados e:ternos, como no %ccess* ( modelo 7ue se"ue tratar desta Pltima opo* ( terceiro tJpico tem como opo !asicamente o uso de "rfico ou ta!elas, e 8 prefervel decidir de antemo 7uais dados sero analisados e 7uais tipos de "rficos sero reportados* 25
(!serva?es Importantes
2* ] importante dei:ar claro ao usurio o 7ue a aplicao faG e suas limita?es* Uma forma de se faGer isso 8 faGer uma criando uma planil/a e:plicativa com a descrio do modelo a ser desenvolvido, 7ue o usurio ir ver assim 7ue a!rir o ar7uivo em E:cel* %s e:plica?es mais detal/adas podem ser dadas em cai:as de dilo"o, por e:emplo* 0* en/a o /!ito de criar uma su!-rotina principal 7ue c/ama as outras su!rotinas* ] prefervel 7ue estas e:ecutem pe7uenas tarefas ao inv8s de se usar uma Pnica su!-rotina 7ue realiGe muitas tarefas* 5* +ecida o 7ue pode ser feito "raficamente em veG de em tempo real* % interface do E:cel oferece maneiras muito rpidas de criar "rficos ou ta!elas, ou inserir fJrmulas* Portanto se no modelo, por e:emplo, ser e:i!ido um "rfico, podese criar uma planil/a com o KtemplateL desse "rfico e ento manipul-lo pelo #$%, alterando o 7ue for necessrio* % id8ia 8 7ue 7uanto mais elementos puderem ser feitos "raficamente pela interface do E:cel, menos esforo ser despendido na pro"ramao*
26
Ci"ura A*2
Ci"ura A*0
27
Ci"ura A*5
Ci"ura A*6
Para 7ue a aplicao funcione corretamente, 8 necessrio 7ue o ar7uivo em %ccess se c/ame ransporte*md! e esteja na mesma pasta 7ue o ar7uivo ransporte*:lsm* Este ar7uivo precisa conter 5 ta!elas H+emand, Capacit' e UnitCostI com o formato como mostra a fi"ura a!ai:o&
28
Ci"ura A*-
Esse ar7uivo pode ser alterado desde 7ue manten/a o formato acima* Pode-se adicionar ou e:cluir mais f!ricas e revendedores ou alterar nomes e custos*
29
Ci"ura 21*2
30
Ci"ura 21*0
Ci"ura 21*5
21*5 .anela
/is@or)!oo)
Para "arantir 7ue a planil/a e:plicativa aparea 7uando o ar7uivo 8 a!erto, e 7ue as outras no apaream, o se"uinte cJdi"o 8 implementado na janela /is@or)!oo)* Private Sub Workbook_Open() Worksheets("Modelo").Visible = False Worksheets("Resultados").Visible = False Worksheets("Explicativa").Activate Range("G18").Select End Sub
31
Ci"ura 21*6
Cada cai:a possui a propriedade de mPltipla seleo HMultiSelectI escol/ida como 0-fmMultiSelectE:tended, 7ue permite o usurio selecionar mais de um item das cai:as se"urando a tecla Ctrl* EventBandlers % su!-rotina !tnCancel4Clic) e:ecuta sua funo usual, saindo do formulrio e terminando a aplicao* % su!rotina !tn(Z4clic), usa a propriedade Selected 7ue 8 K1-!ased inde:in"L para capturar as f!ricas e revendedores selecionados em vetores pP!licos K2-!ased inde:in"L HselectedPlants e selectedEetailersI 7ue esto declarados no incio do mJdulo* +epois de capturar esses vetores, constrJi-se com eles duas strin"s Plants=ist e Eetailers=ist 7ue sero usados para capturar os custos unitrios* +essa forma se o usurio selecionar, por e:emplo, as f!ricas $oston, NeM _or), oronto, Plants=ist ser KHT$oston`,`NeM _or),` oronto`IL* % su!-rotina UserCorm4InitialiGe preenc/e as cai:as de lista"em com todas as f!ricas e revendedores e:istentes no !anco de dados, 7ue esto armaGenados nos vetores e:istin"Plant e e:istin"Eetailer* ( cJdi"o completo encontra-se a!ai:o&
32
Private Sub btnCancel_Click() Unload Me End End Sub Private Sub btnOK_Click() ' Preenche um vetor, selectedPlant, com as fbricas selecionadas. nSelectedPlants = 0 For i = 1 To lbPlants.ListCount If lbPlants.Selected(i - 1) Then nSelectedPlants = nSelectedPlants + 1 ReDim Preserve selectedPlant(nSelectedPlants) selectedPlant(nSelectedPlants) = lbPlants.List(i - 1) End If Next If nSelectedPlants = 0 Then MsgBox "Favor selecionar ao menos uma fbrica.", vbExclamation, _ "Seleo requerida" Exit Sub End If ' Constri uma string, PlantList, que tem a seguinte estrutura: ' ('_','_','_'), dependendo das fbricas selecionadas. plantList = "(" For i = 1 To nSelectedPlants If i < nSelectedPlants Then plantList = plantList & "'" & selectedPlant(i) & "'," Else plantList = plantList & "'" & selectedPlant(i) & "')" End If Next ' Preenche um vetor, selectedRev, com os revendedores selecionados. nSelectedRetailers = 0 For i = 1 To lbRetailers.ListCount If lbRetailers.Selected(i - 1) Then nSelectedRetailers = nSelectedRetailers + 1 ReDim Preserve selectedRetailer(nSelectedRetailers) selectedRetailer(nSelectedRetailers) = lbRetailers.List(i - 1) End If Next If nSelectedRetailers = 0 Then MsgBox "Favor selecionar ao menos um revendedor.", vbExclamation, _ "Seleo requerida" Exit Sub End If
33
selectedRetailer(nSelectedRetailers) = lbRetailers.List(i - 1) End If Next If nSelectedRetailers = 0 Then MsgBox "Favor selecionar ao menos um revendedor.", vbExclamation, _ "Seleo requerida" Exit Sub End If ' Constri uma string, RevList, que tem a seguinte estrutura: ' ('_','_','_'), dependendo dos revendedores selecionados. retailerList = "(" For i = 1 To nSelectedRetailers If i < nSelectedRetailers Then retailerList = retailerList & "'" & selectedRetailer(i) & "'," Else retailerList = retailerList & "'" & selectedRetailer(i) & "')" End If Next Unload Me End Sub Private Sub UserForm_Initialize() ' Preenche as caixas de listagem com os vetores. lbPlants.List = existingPlant lbRetailers.List = existingRetailer End Sub
34
Option Explicit Option Base 1 Public existingPlant() As String, existingRetailer() As String Public nSelectedPlants As Integer, nSelectedRetailers As Integer Public selectedPlant() As String, selectedRetailer() As String Public plantList As String, retailerList As String ' Declara objetos de conexo e registro do ADO. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset
Macro KPrincipalL
Sub Main Transport() ' Essa a macro que executada quando o boto anexado na planilha ' Explicativa clicado. ' Desliga a funo de atualizao da tela do Excel para aumentar o desempenho da ' aplicao Application.ScreenUpdating = False ' Abre uma conexo com o banco de dados do Access, assumindo que esse ' banco e a pasta de trabalho do Excel estejam na mesma pasta. With cn .ConnectionString = "Data Source=" & ThisWorkbook.Path & "\Transporte.mdb" .Provider = "Microsoft Jet 4.0 OLE DB Provider" .Open End With ' Importa os dados desejados do banco. Call GetPlantAndRetailers frmInputs.Show Call CheckSolverLimit Call EnterModelData ' Fecha a conexo com o banco de dados. cn.Close ' Configura e soluciona o modelo. Call EnterFormulas Call SetAndRunSolver End Sub
35
Ruando o !oto KE:ecutar a aplicaoL na ta!ela e:plicativa 8 clicado, a se"uinte macro 8 rodada* Essa macro c/ama outras su!-rotinas 7ue e:traem os dados do !anco de dados do %ccess, desenvolvem o modelo, e:ecutam o Solver e informam o resultado*
Macro DetPlant%ndEetailers
Essa macro importa os dados das ta!ela KCapacit'L e K+emandL* Isso pode ser feito atrav8s de uma sentena em SR=& KSelect Plant Crom Capacit'L* Ento, os nomes das f!ricas so armaGenados em vetores* ( mesmo ocorre com os nomes dos revendedores* Sub GetPlantAndRetailers() ' Essa subrotina pega os nomes das fbricas e revendedores no banco de dados ' para posteriormente preencher as caixas de listagem Dim nExisitingPlants As Integer, nExisitingRetailers As Integer Dim i As Integer, j As Integer Dim SQL As String ' Pega os nomes das fbricas na tabela Capacity para preencher o vetor existingPlant. SQL = "Select Plant From Capacity" With rs .Open SQL, cn nExisitingPlants = 0 Do While Not .EOF nExisitingPlants = nExisitingPlants + 1 ReDim Preserve existingPlant(nExisitingPlants) existingPlant(nExisitingPlants) = .Fields("Plant").Value .MoveNext Loop .Close End With ' Pega os nomes dos revendedores na tabela Demand para preencher ' o vetor existingRetailers. SQL = "Select Retailer from Demand" With rs .Open SQL, cn nExisitingRetailers = 0 Do While Not .EOF nExisitingRetailers = nExisitingRetailers + 1
36
ReDim Preserve existingRetailer(nExisitingRetailers) existingRetailer(nExisitingRetailers) = .Fields("Retailer").Value .MoveNext Loop .Close End With End Sub
37
Sub EnterModelData() ' A seguinte macro utiliza o ADO para trasnportar os dados ' do banco de dados para as clulas da planilha Modelo. Dim SQL As String Dim i As Integer, j As Integer Dim topCell As Range ' Apaga tudo da plhanilha Modelo. With Worksheets("Modelo") .Cells.Clear .Activate End With 'Nomeia as clulas. Range("A1").Value = "Problema de Transporte" Range("B3").Value = "Custos Unitrios" Range("B5").Value = "Fbricas" Range("D3").Value = "Revendedores" Set topCell = Range("C4") ' Adiciona os nomes das fbricas e revendedores. With topCell For i = 1 To nSelectedPlants .Offset(i, 0).Value = selectedPlant(i) Next For j = 1 To nSelectedRetailers .Offset(0, j).Value = selectedRetailer(j) Next End With ' Pega os dados com a seguinte sentena em SQL, e preenche as clulas de 'Custo Unitrio. SQL = "Select UC.UnitCost " _ & "From (UnitCost UC Inner Join Capacity C On UC.PlantID = C.PlantID) " _ & "Inner Join Demand D On UC.RetailerID = D.RetailerID " _ & "Where C.Plant In " & plantList & " And D.Retailer In " & retailerList With rs .Open SQL, cn For i = 1 To nSelectedPlants For j = 1 To nSelectedRetailers topCell.Offset(i, j).Value = .Fields("UnitCost").Value .MoveNext Next Next .Close End With
38
.Open SQL, cn For i = 1 To nSelectedPlants For j = 1 To nSelectedRetailers topCell.Offset(i, j).Value = .Fields("UnitCost").Value .MoveNext Next Next .Close End With ' Nomeia as clulas de Custo Unitrio With topCell Range(.Offset(1, 1), .Offset(nSelectedPlants, nSelectedRetailers)) _ .Name = "UnitCosts" End With ' Preenche os valores de capacidade. Set topCell = Range("C4").Offset(0, nSelectedRetailers + 2) topCell.Value = "Capacitidades" SQL = "Select Capacity From Capacity " & _ "Where Plant In " & plantList With rs .Open SQL, cn For i = 1 To nSelectedPlants topCell.Offset(i, 0).Value = .Fields("Capacity").Value .MoveNext Next .Close End With ' Nomeia as clulas de capacidades. With topCell Range(.Offset(1, 0), .Offset(nSelectedPlants, 0)).Name = "Capacities" End With ' Preenche os valores de demanda. Set topCell = Range("C4").Offset(nSelectedPlants + 2, 0) topCell.Value = "Demandas" SQL = "Select Demand From Demand " & _ "Where Retailer In " & retailerList With rs .Open SQL, cn For j = 1 To nSelectedRetailers topCell.Offset(0, j).Value = .Fields("Demand").Value .MoveNext Next .Close End With 39
topCell.Value = "Demandas" SQL = "Select Demand From Demand " & _ "Where Retailer In " & retailerList With rs .Open SQL, cn For j = 1 To nSelectedRetailers topCell.Offset(0, j).Value = .Fields("Demand").Value .MoveNext Next .Close End With ' Nomeia as clulas de demanda. With topCell Range(.Offset(0, 1), .Offset(0, nSelectedRetailers)).Name = "Demands" End With End Sub %o final dessa macro, todos os dados necessrios para o pro!lema esto devidamente dispostos na planil/a KModelo*
.BorderAround Weight:=xlMedium, ColorIndex:=3 End With ' Entra com as formulas para as somas das linhas e colunas das "Quantidades enviadas" e "Quantidade recebidas". Set topCell = Range("Shipments").Cells(1) With topCell .Offset(-1, nSelectedRetailers).Value = "Quantidades enviadas" .Offset(nSelectedPlants, -1).Value = "Quantidades recebidas" Set outOfRange = Range(.Offset(0, nSelectedRetailers), _ .Offset(nSelectedPlants - 1, nSelectedRetailers)) Set intoRange = Range(.Offset(nSelectedPlants, 0), _ .Offset(nSelectedPlants, nSelectedRetailers - 1)) End With With outOfRange .Name = "SentOut" .FormulaR1C1 = "=SUM(RC[-" & nSelectedRetailers & "]:RC[-1])" End With With intoRange .Name = "SentIn" .FormulaR1C1 = "=SUM(R[-" & nSelectedPlants & "]C:R[-1]C)" End With End With ' Calcula a clula de custo total. Set topCell = Range("SentIn").Item(1).Offset(2, 0) With topCell .Formula = "=SumProduct(UnitCosts,Shipments)" .Name = "TotalCost" .NumberFormat = "R$#,##0_);(R$#,##0)" .Offset(0, -2).Value = "Custo Total" Range("A1").Select End Sub
Macro Setup%ndEunSolverHI
Essa macro confi"ura e e:ecuta o Solver* infactvel* am!8m c/eca se al"uma soluo 8
41
Sub SetupAndRunSolver() Dim solverStatus As Integer With Worksheets("Model") .Visible = True .Activate End With SolverReset SolverAdd Range("Shipments"), 3, 0 SolverAdd Range("SentOut"), 1, "Capacities" SolverAdd Range("SentIn"), 3, "Demands" SolverOptions AssumeLinear:=True, AssumeNonNeg:=True SolverOk SetCell:=Range("TotalCost"), MaxMinVal:=2, _ ByChange:=Range("Shipments") ' Executa o Solver. Se no existir nenhuma soluo factvel, ' o problema retorna ao incio pedindo para o usurio selecionar outras entradas. solverStatus = SolverSolve(UserFinish:=True) If solverStatus = 5 Then MsgBox "No existe soluo factvel. Tente uma combinao diferente de " _ & "fbricas e revendedores.", vbExclamation, "Infactibilidade" Call MainTransport Else Worksheets("Model").Visible = False Call CreateReport End If End Sub
Macro CreateEeport
ransfere o custo total e as informa?es so!re as rotas com remessas positivas para a planil/a KEesultadosL* am!8m ser informado se no e:istir nen/um transporte a partir de uma determinada f!rica*
42
Sub CreateReport() Dim i As Integer, j As Integer Dim nShippedTo As Integer, amountShipped As Integer Dim topCell As Range ' Apaga todo o contedo da planilha menos o boto para executar outro problema. With Worksheets("Resultados") .Cells.Clear .Visible = True .Activate End With ' Entra com os valores da clulas e configuraes de cor e estilo. With Range("B1") .Value = "Soluo tima" With .Font .Size = 14 .Bold = True End With End With With ActiveWindow .DisplayGridlines = False .DisplayHeadings = False End With Cells.Interior.ColorIndex = 40 Columns("B:B").Font.ColorIndex = 1 Columns("C:C").Font.ColorIndex = 5 Range("B1").Font.ColorIndex = 1 ' Para cada rota com quantidades positivas, imprime quanto transportado. Set topCell = Range("B3") For i = 1 To nSelectedPlants If Range("SentOut").Cells(i).Value > 0.1 Then With topCell .Value = " Produtos enviados de " & selectedPlant(i) .Font.Bold = True End With nShippedTo = 0 For j = 1 To nSelectedRetailers amountShipped = Range("Shipments").Cells(i, j).Value If amountShipped > 0.01 Then nShippedTo = nShippedTo + 1 topCell.Offset(nShippedTo, 1).Value = _ amountShipped & " unidades para " & selectedRetailer(j) End If Next Set topCell = topCell.Offset(nShippedTo + 2, 0) Else 43
With topCell .Value = "Nenhum produto enviado de " & selectedPlant(i) .Font.Bold = True End With Set topCell = topCell.Offset(2, 0) End If Next ' Imprime o custo total With Range("G3") .Value = "O custo total de trasponte " & _ Format(Range("TotalCost").Value, "R$#,##0;(R$#,##0)") .Font.Bold = True End With Range("A1").Select End Sub
44
Concluso
Pode-se notar pontos favorveis e desfavorveis ao implementar uma modela"em utiliGando #$%* % mel/or vanta"em em utiliGar essa lin"ua"em 8 7ue ela possui uma ilimitada fle:i!ilidade* (u seja, com o E:cel podemos realiGar os clculos, importar e e:portar dados com outras e:tens?es, incluir !i!liotecas 7ue faGem uso de outras lin"ua"ens, criar visualiGa?es convenientes para o usurio, etc* %o final, todo o contePdo est em um Pnico ar7uivo 7ue pode ser "ravado e e:ecutado em 7ual7uer outra m7uina 7ue possua o softMare* %l8m disso, provavelmente todas as empresas possuem o Microsoft E:cel instalado em suas m7uinas, e a muitas pessoas esto de al"uma maneira familiariGadas com sua interface* % lin"ua"em #$% 8 uma lin"ua"em fcil de se aprender, visto a "rande 7uantidade de livros e Me!sites so!re o assunto* %l8m do mais, o pes7uisador de o!jetos e o intellisense so ferramentas 7ue facilitam ainda mais o aprendiGado* Como desvanta"em, temos a lenta performance* % e:ecuo de uma su!-rotina 8 feita lin/a por lin/a* Cada lin/a 8 lida, c/ecada para ver se no / erros na sinta:e, compilada e e:ecutada* Isso torna a e:ecuo muito lenta dependendo do taman/o do pro!lema, se comparada com outras aplica?es desenvolvidas em C, por e:emplo* %l8m disso, e:iste a limitao do nPmero de c8lulas, cerca de ;-*-5; lin/as para as vers?es 0115 ou anteriores* +eve-se tam!8m ter cuidado ao manipular o ar7uivo, pois al"umas altera?es nas planil/as podem modificar o cJdi"o, "erando conflitos* Conclui-se 7ue deve-se ter !om senso ao escol/er o #$% como ferramenta para o desenvolvimento de modelos de otimiGao* %pesar da "rande funcionalidade, essa 8 uma opo vivel apenas para pro!lemas de pe7uena e m8dia escala, e em 7ue minimiGar o tempo de e:ecuo no seja o principal o!jetivo*
45
EeferFncias
2I utorial so!re modela"em utiliGando o Solver& /ttp&WWMMM*ime*unicamp*!rWamorettiWms60>W0sem0121W utorialE:cel*doc 0I =inear pro"rammin" and netMor) floMs W Mo)/tar S* $aGaraa, .o/n .* .arvis, Banif +* S/erali* 5I E%M%=B(, .ose %ntonio %* H.ose %ntonio %lvesI* SR=& SR= a lin"ua"em dos !ancos de dados* So Paulo, SP& $er)ele'*
46
$i!lio"rafia
2I %l!ri"/t, S* C*S #$% for Modelers +evelopin" +ecision Support S'stems Mit/ Microsoft (ffice E:cel* 0121 ed* Sout/-@estern Cen"a"e =earnin"*
47