Notifications
Clear all

Qual a diferença em usar set ou o caminho completo?

13 Posts
4 Usuários
0 Reactions
2,524 Visualizações
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

No meu trabalho dimensionei dois workbooks diferentes e quatro worksheets diferentes, tambem utilizei o set para facilitar meu trabalho com cada. Até aí não houve erro.
Porém ao utilizar algumas funções eu percebi que especificar o caminho por, por exemplo:
wbp e wbm sao workbooks
wsh,wsm,wsc e wse são worksheets

wbp.wsh.Range("A1:D4").PrintOut ---> erro: "o objeto não aceita esta propriedade ou método"
Workbooks("blabla.xml").Worksheets("Planilha1").Range("A1:D4").PrintOut ---> funciona perfeitamente

Aí me pergunto, porque?
E qual a vantagem então de eu definir os atalhos (wb* e ws*) se não vou poder usá-los mesmo.

Ah, também ocorre o mesmo erro se usado como controle para um while:

while wbp.wsh.Cells(i,3).Value <>" " ---> erro: "o objeto não aceita esta propriedade ou método"
while Workbooks("blabla.xml").Worksheets("Planilha1").Cells(i,3).Value <>" " ---> funciona perfeitamente

 
Postado : 25/11/2016 8:28 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Boa tarde!!

Leia:
https://usuariosdoexcel.wordpress.com/2 ... rucao-set/

Att

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 25/11/2016 9:32 am
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

Bom, entendi a diferença e o porque do Set. Mas continuo sem entender o porque do erro. Se ao utilizar o Set eu torno a variavel um objeto, entao os comando que necessitam de objetos poderiam ser feitas através destas variáveis, e não puderam.
Exemplo concreto:

Dim wbp As Workbook
Dim wsm As Worksheet
Set wbp = Workbooks("plano de manutençao1.xlsm")
Set wsm = Worksheets("Próximas Manutenções")

While wbp.wsm.Cells(i, 1).Value <> ""

Isto dá o erro de "o objeto não aceita esta propriedade ou método".

Lembrando que o Workbook "plano de manutençao1.xlsm" já está aberto e a worksheet está visível.

 
Postado : 25/11/2016 11:31 am
(@mprudencio)
Posts: 2749
Famed Member
 

Tente assim


Dim wbp As Workbook
Dim wsm As Worksheet
Set wbp = Workbooks("plano de manutençao1.xlsm")
Set wsm = Worksheets("Próximas Manutenções")

'Acrescente essa linha
wbp.active

While wbp.wsm.Cells(i, 1).Value <> ""

Marcelo Prudencio
Microsoft Excel Brasil no Facebook

"Começar já é a metade do caminho."
Autor Desconhecido

Simplifica que simples fica.
Nicole Tomazella.

"O Simples é Sempre Melhor Que o Complicado"
Jorge Paulo Lemann.

 
Postado : 25/11/2016 2:11 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Boa noite!!

Poste sua rotina por completa, pois eu acho que você está a tentar ao que não possamos verificar.

Do While wbp.wsm.Cells(i, 1).Value <> ""
'Poste toda sua rotina (por completa)
Loop

Eu não estou entendendo oque você quer a final...

Att

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 25/11/2016 8:09 pm
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

MPrudencio:
Ao adicionar a linha que você citou o seguinte erro aparece:
"O objeto não aceita esta propriedade ou método"

alexandrevba:

Tudo bem, segue abaixo o código completo, já que o while é quase tudo mesmo, resolvi postar tudo de uma vez. Só espero que não fique muito confuso.

Public Sub Manut()

Dim wbp, wbc As Workbook
Set wbp = Workbooks("plano de manutençao1.xlsm")
Dim wsc, wsm, wsh As Worksheet
Set wsc = Worksheets("Clientes")
Set wsm = Worksheets("Próximas Manutenções")
Dim i, UM, hr, c, m, z, b, menor As Single
Dim dt As Date
Dim tm(), r(), dia(), obs As String
Dim intCount As Integer

i = 3

Application.EnableEvents = False
Application.ScreenUpdating = False

wbp.wsm.Range("A3:B4").ClearContents                ' ->              Erro "O objeto não aceita esta propriedade ou método" (erro some se usar: Workbooks("plano de manutençao1.xlsm"). Worksheets("Próximas Manutenções")..Range("A3:B4").ClearContents

While wbp.wsc.Cells(i, 1).Value <> ""                   ' ->                Erro "O objeto não aceita esta propriedade ou método" (erro também some se fizer como acima)
    
    Workbooks.Open ("C:UsersUsuarioDesktopBrunomelhoriasclientes" & wbp.wsc.Cells(i, 1).Value)                            '-> mesmo erro
    Set wbc = Workbooks(wbp.ws.Cells(i, 1).Value)                            '-> mesmo erro
    Set wsh = Worksheets("Histórico de Manutenções")
    hr = wbp.wsc.Cells(i, 5).Value + (DateDiff("d", wsc.Cells(i, 7), Date) * wsc.Cells(i, 8))         '-> ainda não testei, mas deve dar o mesmo erro
    obs = "Existem menos de 2 dias de diferença entre as manutenções de "

'saber se existe dados no histórico
    If wbc.wsh.Cells(3, 1).Value = "" Then
        c = 1
    Else
        c = 2
    End If
'Separar os tipos de manutenção
    tm = split(wbp.wsc.Cells(i, 5), ",")
    
    For intCount = LBound(tm) To UBound(tm)
      Debug.Print Trim(tm(intCount))
    Next
   
'Sem dados no histórico
    If c = 1 Then
        m = (wbp.wsc.Cells(i, 6).Value + CInt(tm(0)) - hr)  wbp.wsc.Cells(i, 8)
        wbp.wsm.Cells(i, 1).Value = wbp.wsc.Cells(i, 1).Value
        wbp.wsm.Cells(i, 2).Value = DateAdd("d", Date, m)
        wbp.wsm.Cells(i, 3).Value = CInt(tm(0))
    Else
        For z = 0 To intCount   ' pega a ultima linha de cada tipo de manutenção
            b = 3
            While wbc.wsh.Cells(b, 1) <> ""
             If wbc.wsh.Cells(b, 1).Value = CInt(tm(z)) Then
                r(z) = b
                b = b + 1
             Else
                b = b + 1
             End If
            Wend
        Next
        For z = 0 To intCount      'calcula quantos dias para prox manutenção para cada tipo
            dia(z) = (wbc.wsh.Cells(r(z), 2) + CInt(tm(z)) - hr)  wbp.wsc.Cells(i, 8)
        Next
        For z = 1 To intCount   'compara o dia de manutenções para casos menores que 2
            If Abs(dia(z - 1) - dia(z)) <= 2 Then
                obs = obs + tm(z - 1) + "e" + tm(z)
            
            End If
        Next
        If obs <> "" Then
            If DateAdd("d", Date, dia(0)) > DateAdd("d", Date, dia(1)) Then
                wbp.wsm.Cells(i, 1).Value = wbp.wsc.Cells(i, 1).Value
                wbp.wsm.Cells(i, 2).Value = DateAdd("d", Date, dia(1))
                wbp.wsm.Cells(i, 3).Value = CInt(tm(0)) + " + " + CInt(tm(1))
                wbp.wsm.Cells(i, 4).Value = obs
            Else
                wbp.wsm.Cells(i, 1).Value = wbp.wsc.Cells(i, 1).Value
                wbp.wsm.Cells(i, 2).Value = DateAdd("d", Date, dia(0))
                wbp.wsm.Cells(i, 3).Value = CInt(tm(0)) + " + " + CInt(tm(1))
                wbp.wsm.Cells(i, 4).Value = obs
            End If
        Else
            If DateAdd("d", Date, dia(0)) > DateAdd("d", Date, dia(1)) Then
                wbp.wsm.Cells(i, 1).Value = wbp.wsc.Cells(i, 1).Value
                wbp.wsm.Cells(i, 2).Value = DateAdd("d", Date, dia(1))
                wbp.wsm.Cells(i, 3).Value = CInt(tm(1))
            Else
                wbp.wsm.Cells(i, 1).Value = wbp.wsc.Cells(i, 1).Value
                wbp.wsm.Cells(i, 2).Value = DateAdd("d", Date, dia(0))
                wbp.wsm.Cells(i, 3).Value = CInt(tm(0))
            End If
        End If
    End If
    wbc.Close
    i = i + 1
Wend

wsm.Columns("A:D").AutoFit

' Reordenar

    ActiveWorkbook.Worksheets("Próximas Manutenções").ListObjects("Tabela2").Sort. _
        SortFields.Clear
    ActiveWorkbook.Worksheets("Próximas Manutenções").ListObjects("Tabela2").Sort. _
        SortFields.Add Key:=Range("Tabela2[[#All],[Data]]"), SortOn:=xlSortOnValues _
        , Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Próximas Manutenções").ListObjects("Tabela2"). _
        Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    
Application.EnableEvents = True
Application.ScreenUpdating = True

MsgBox ("Planilha atualizada")
    
End Sub
 
Postado : 28/11/2016 5:39 am
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

Tente assim


Dim wbp As Workbook
Dim wsm As Worksheet
Set wbp = Workbooks("plano de manutençao1.xlsm")
Set wsm = Worksheets("Próximas Manutenções")

'Acrescente essa linha
wbp.active

While wbp.wsm.Cells(i, 1).Value <> ""

Na verdade o comando activate ajuda sim, mas é activate, e não active
hahahahahaha
Enfim, estou readaptando meu texto para, sempre que for trocar de workbook usar o comando activate, para deixar meu código mais claro. Porém os erros persistem.

 
Postado : 28/11/2016 6:25 am
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

Ta, acho q encaminhei a solução do meu problema

Ao usar os caminhos já "setados" como wbp.wsc.cells... ele dá problema.
Mas ao utilizar
wbp.activate
wsc.cells... vai de boa

Outro erro era que ao "setar" um workbook eu estava me esquecendo do .xlsx

Mesmo assim gostaria de entender o porque de não poder/conseguir wbp.wsc.cells

Enquanto isso, valeu pela ajuda gente

 
Postado : 28/11/2016 6:37 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Boa tarde!!

Eu ainda estou boiando, mas tente...
Seguir esse raciocínio..

Public Sub Manut()

Dim wbp, wbc As Workbook
Set wbp = Workbooks("plano de manutençao1.xlsm")
Dim wsc, wsm, wsh As Worksheet
Set wsc = Worksheets("Clientes")
Set wsm = wbp.Worksheets("Próximas Manutenções") '<-- Veja...
Dim i, UM, hr, c, m, z, b, menor As Single
Dim dt As Date
Dim tm(), r(), dia(), obs As String
Dim intCount As Integer

i = 3

Application.EnableEvents = False
Application.ScreenUpdating = False

wsm.Range("A3:B4").ClearContents  '<-- Veja...

While wbp.wsc.Cells(i, 1).Value <> ""  '<-- Veja...

Att

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 28/11/2016 11:55 am
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

Boa tarde!!

Eu ainda estou boiando, mas tente...
Seguir esse raciocínio..

Public Sub Manut()

Dim wbp, wbc As Workbook
Set wbp = Workbooks("plano de manutençao1.xlsm")
Dim wsc, wsm, wsh As Worksheet
Set wsc = Worksheets("Clientes")
Set wsm = wbp.Worksheets("Próximas Manutenções") '<-- Veja...
Dim i, UM, hr, c, m, z, b, menor As Single
Dim dt As Date
Dim tm(), r(), dia(), obs As String
Dim intCount As Integer

i = 3

Application.EnableEvents = False
Application.ScreenUpdating = False

wsm.Range("A3:B4").ClearContents  '<-- Veja...

While wbp.wsc.Cells(i, 1).Value <> ""  '<-- Veja...

Att

Então, por algum motivo esta sua gera erros.
Eu consegui resolver aqui o problema, se quiserem eu posto a versão que funciona, e com uma pequena alteração, quem também estiver curioso pode ver o erro que acontece.
Para quem for verificar, percebam que a unica diferença está no primeiro while.

 
Postado : 28/11/2016 12:05 pm
EdsonBR
(@edsonbr)
Posts: 1057
Noble Member
 

Biogas, um detalhe importante em sua declaração de variáveis. Em seu post inicial, vc diz:

:...wbp e wbm sao workbooks
wsh,wsm,wsc e wse são worksheets...

No entanto, o dimensionamento dessas variáveis em seu código está assim:

Dim wbp, wbc As Workbook
...
Dim wsc, wsm, wsh As Worksheet

Dessa maneira, somente wbc é um objeto tipo Workbook e somente wsh é um objeto tipo Worksheet. As demais são Variant. No VBA tem que declarar todas as variáveis, de uma em uma, com o tipo desejado:

Dim wbp As Workbook, wbc As Workbook
...
Dim wsc As Worksheet, wsm As Worksheet, wsh As Worksheet

Outro fator a considerar é na atribuição e qualificação dos objetos mais internos:
Vc usou, no início:
Set wbp = Workbooks("plano de manutençao1.xlsm")

Já que wsc e wsm são planilhas contidas em wbp, então seria prudente qualificar esses objetos adequadamente (inclusive até dispensaria o uso do Activate):
Set wsc =wbp. Worksheets("Clientes")
Set wsm =wbp. Worksheets("Próximas Manutenções")

______
Mas as duas observações acima não refletem a causa do problema do erro propriamente dito. O verdadeiro problema parece estar nessa qualificação redundante no seguinte trecho (que vc já consertou na versão nova):

While wbp.wsc.Cells(i, 1).Value <> ""

Aqui dá erro mesmo, pois wsc já contém uma planilha e vc tenta requalificá-la com o objeto pai. Para ilustrar o problema, faça o teste abaixo, passo a passo, e veja como se dá o problema:

Sub Teste()
   Dim x As Workbook, y As Worksheet
   Set x = ThisWorkbook
   Set y = x.Worksheets(1)
   MsgBox x.Worksheets(1).Name  'Passa
   MsgBox y.Name 'Passa
   MsgBox x.y.Name 'Aqui não passa, dá erro "O objeto não aceita esta propriedade ou método"
End Sub

 
Postado : 28/11/2016 1:47 pm
(@biogas)
Posts: 21
Eminent Member
Topic starter
 

Interessante!

Então, hora de qualificar as planilhas o melhor é já identificar a qual arquivo elas pertencem. Acredito que isto me permite depois buscar só pelo index da planilha então.

Dim x As Workbook, y As Workbook, s As Worksheet, d As Worksheet
Set x = Workbooks("Pasta1.xlsx")
Set y = Workbooks("Pasta.xlsx")
Set s = x.Worksheets("Planilha1")
Set d = y.Worksheets("Planilha1")

If s.cells(1,2)="" and d.cells(1,2)="" then
MsgBox ("funciona")
else
End If
 

ou

Sub teste()
Dim x As Workbook, y As Workbook, s As Worksheet, d As Worksheet
Set x = Workbooks("Pasta1.xlsx")
Set y = Workbooks("Pasta2.xlsx")
Set s = x.Worksheets("Planilha1")
Set d = y.Worksheets("Planilha1")
Dim i As Integer

i = 1

While s.Cells(i, 1).Value = "" And d.Cells(i, 1).Value = ""
    i = i + 1
Wend


MsgBox ("valor" & i)

End Sub

Eu testei os dois e deu certo. Acredito então que posso usar com segurança diretamente o index da planilha, sem precisar toda vez especificar qual workbook, uma vez que este ja foi especificado quando o objeto worksheet foi qualificado.
Espero não ter concluido nada errado.
E muito obrigado a todos pela ajuda, assim que o EdsonBR me confirmar que é isso mesmo, marcarei como resolvido.

 
Postado : 29/11/2016 5:22 am
EdsonBR
(@edsonbr)
Posts: 1057
Noble Member
 

Vai feliz, Biogas, assimilou corretamente! ;)

 
Postado : 29/11/2016 5:44 am