Olá, caros colegas.
A pergunta é aparentemente simples:
Como percorrer registro por registro de um subformulário (todos os seus registros) durante a rotina de percorrer registro por registro do formulário principal?
Por precaução, vou esmiuçar todos os detalhes para evitar desperdício de tempo dos senhores em elaborar sugestões que, talvez, já se perceberiam inviáveis.
Em meu BD, eu tive que criar novos campos em uma tabela que são preenchidos com base em vários cálculos (envolvendo assinatura digital e outras complexidades).
Tudo já está funcionando perfeitamente para os registros lançados após a última versão do aplicativo (destaco que esse sucesso deve-se em parte à ajuda obtida neste fórum; Obrigado!).
Agora, eu preciso "preencher" esses novos campos nos registros antigos (retroativo a Setembro de 2018) e, para isso, criei uma rotina que, para incluir os dados automatizados, basta que eu percorra registro por registro (dando foco em um campo específico desse subformulário).
No entanto, o BD (com dezenas de tabelas) é gerenciado por 9 formulários e, dentro deles, por um ou dois subformulários (sendo o subform existente em todos os 9 exatamente aquele que traz a tabela que eu preciso atualizar).
Não adianta eu abrir apenas esse subformulário (ou criar um novo formulário com base na tabela em questão), pois os dados a serem incluídos nos registros anteriores dependem dos dados tanto dessa tabela como das outras 9 tabelas ligadas aos 9 formulários principais. E não é só isso (aqui está o maior complicador)! Um dos dados refere-se tão-somente à posição do registro do subformulário com referência ao formulário principal a que está atrelado ("nº sequencial do registro" ou "página do subform"). Este último dado foi necessário para viabilizar a assinatura digital e é exatamente ele que impede que eu use apenas a tabela principal para a atualização.
Exemplo hipotético:
Form Principal: Cliente (1000 registros)
Subformulário: Compra (entre nenhum item e dezenas de itens, sendo cada item = 1 registro)
O bendito campo no SubForm!Compra = [pag]
Como eu não posso mudar a ordem dos itens, acredito que só me sobra a opção de percorrer registro por registro:
Para fazer a varredura, registro a registro, acredito que a melhor opção seja, basicamente, usar o comando:
DoCmd.GoToRecord , , acNext
Mas eu não estou conseguindo fazer a "varredura" no subformulário. Aliás, eu consigo fazer apenas a varredura completa no subformulário ligado ao 1º registro do formulário principal.
A partir do segundo registro percorrido (do form principal), ele foca apenas no "registro 1" do subformulário (ignorando eventuais outros registros).
Tentei de tudo que eu pude imaginar (mudando o foco várias vezes do principal para o subform e vice-versa), mas sem sucesso.
O subformulário tem a seguinte informação em um controle calculado (informação não incluída no BD): [nº_pág] e [total_páginas] (página = nº sequencial do registro do subform)
Incluí no Formulário principal o mesmo controle (com referência expressa ao subformulário).
Portanto, ao percorrer (manualmente) o formulário principal, em seu corpo já consta, em destaque, o dado do subformulário. Ex.: [5] = 5 páginas (registros/itens).
Esse dado (nº de itens do subform) seria a solução perfeita, mas por se tratar de um campo calculado, eu não soube como fazer o "automatismo da varredura" dar um tempinho para que tal campo "calcule". Até criei uma função "pausa", mas também falhou.
Após eu encher o meu código de msgboxes e abusar do Me.Refresh, eu descobri que, exceto quanto ao registro em que a varredura se inciou (cuja tela estava aberta; portanto, com foco nele e com todos os campos calculados em ordem), nos registros seguintes o código VBA acusa sempre "zero" como o valor de [total_páginas]. Por que isso?
Tentei usar os comandos abaixo, mas também não obtive êxito ("o objeto não aceita essa propriedade ou método"):
Dim pag As Integer
Dim Total As Integer
pag = Me![F-Em].RecordsetClone.AbsolutePosition + 1
Total = Me![F-Em].RecordsetClone.RecordCount
Como não consigo identificar o número de "itens" (registros) do subformulário relativo ao registro do formulário principal quando da varredura, não tenho como criar os laços necessários para sejam percorridos os registros (excedentes a um) do subformulário.
O código que eu inicialmente acreditava que funcionária é o seguinte:
Início:
Me!numpages.SetFocus
num = Me.numpages.value 'Aqui está o problema: se maior que 1, só recebe o valor "zero", apesar de o controle [numpages] mostrar sempre o valor correto
Me.Refresh
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
If num = 0 ou num = 1 Then 'existindo um único registro ou nenhum no SubForm, passa para o próximo registro do Form principal
Me!CmdoNF.SetFocus
Me!numpages.SetFocus
Me.Refresh
DoCmd.GoToRecord , , acNext
Else 'existindo mais de 2 registros no SubForm, deveria varrer os registros do SubForm
For pag = 1 To (num - 1)
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
DoCmd.GoToRecord , , acNext
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
Next pag
End If
If Not tt = TotalRegistrosFormPrincipal Then
Exit Sub
Else
Goto Início
End If
End Sub
Qualquer ajuda será bem-vinda.
Obrigado pela atenção de todos.
EA
A pergunta é aparentemente simples:
Como percorrer registro por registro de um subformulário (todos os seus registros) durante a rotina de percorrer registro por registro do formulário principal?
Por precaução, vou esmiuçar todos os detalhes para evitar desperdício de tempo dos senhores em elaborar sugestões que, talvez, já se perceberiam inviáveis.
Em meu BD, eu tive que criar novos campos em uma tabela que são preenchidos com base em vários cálculos (envolvendo assinatura digital e outras complexidades).
Tudo já está funcionando perfeitamente para os registros lançados após a última versão do aplicativo (destaco que esse sucesso deve-se em parte à ajuda obtida neste fórum; Obrigado!).
Agora, eu preciso "preencher" esses novos campos nos registros antigos (retroativo a Setembro de 2018) e, para isso, criei uma rotina que, para incluir os dados automatizados, basta que eu percorra registro por registro (dando foco em um campo específico desse subformulário).
No entanto, o BD (com dezenas de tabelas) é gerenciado por 9 formulários e, dentro deles, por um ou dois subformulários (sendo o subform existente em todos os 9 exatamente aquele que traz a tabela que eu preciso atualizar).
Não adianta eu abrir apenas esse subformulário (ou criar um novo formulário com base na tabela em questão), pois os dados a serem incluídos nos registros anteriores dependem dos dados tanto dessa tabela como das outras 9 tabelas ligadas aos 9 formulários principais. E não é só isso (aqui está o maior complicador)! Um dos dados refere-se tão-somente à posição do registro do subformulário com referência ao formulário principal a que está atrelado ("nº sequencial do registro" ou "página do subform"). Este último dado foi necessário para viabilizar a assinatura digital e é exatamente ele que impede que eu use apenas a tabela principal para a atualização.
Exemplo hipotético:
Form Principal: Cliente (1000 registros)
Subformulário: Compra (entre nenhum item e dezenas de itens, sendo cada item = 1 registro)
O bendito campo no SubForm!Compra = [pag]
- Item 1 => [pag] = "AA"
- Item 2 => [pag] = "AB"
- Item 3 => [pag] = "AC"
- Item 4 => [pag] = "AD"
Como eu não posso mudar a ordem dos itens, acredito que só me sobra a opção de percorrer registro por registro:
- Cliente 1: item 1
- Cliente 2: sem nenhum item
- Cliente 3: item 1
- Cliente 3: item 2
- Cliente 3: item 3
- Cliente 4: item 1
Para fazer a varredura, registro a registro, acredito que a melhor opção seja, basicamente, usar o comando:
DoCmd.GoToRecord , , acNext
Mas eu não estou conseguindo fazer a "varredura" no subformulário. Aliás, eu consigo fazer apenas a varredura completa no subformulário ligado ao 1º registro do formulário principal.
A partir do segundo registro percorrido (do form principal), ele foca apenas no "registro 1" do subformulário (ignorando eventuais outros registros).
Tentei de tudo que eu pude imaginar (mudando o foco várias vezes do principal para o subform e vice-versa), mas sem sucesso.
O subformulário tem a seguinte informação em um controle calculado (informação não incluída no BD): [nº_pág] e [total_páginas] (página = nº sequencial do registro do subform)
Incluí no Formulário principal o mesmo controle (com referência expressa ao subformulário).
Portanto, ao percorrer (manualmente) o formulário principal, em seu corpo já consta, em destaque, o dado do subformulário. Ex.: [5] = 5 páginas (registros/itens).
Esse dado (nº de itens do subform) seria a solução perfeita, mas por se tratar de um campo calculado, eu não soube como fazer o "automatismo da varredura" dar um tempinho para que tal campo "calcule". Até criei uma função "pausa", mas também falhou.
Após eu encher o meu código de msgboxes e abusar do Me.Refresh, eu descobri que, exceto quanto ao registro em que a varredura se inciou (cuja tela estava aberta; portanto, com foco nele e com todos os campos calculados em ordem), nos registros seguintes o código VBA acusa sempre "zero" como o valor de [total_páginas]. Por que isso?
Tentei usar os comandos abaixo, mas também não obtive êxito ("o objeto não aceita essa propriedade ou método"):
Dim pag As Integer
Dim Total As Integer
pag = Me![F-Em].RecordsetClone.AbsolutePosition + 1
Total = Me![F-Em].RecordsetClone.RecordCount
Como não consigo identificar o número de "itens" (registros) do subformulário relativo ao registro do formulário principal quando da varredura, não tenho como criar os laços necessários para sejam percorridos os registros (excedentes a um) do subformulário.
O código que eu inicialmente acreditava que funcionária é o seguinte:
Início:
Me!numpages.SetFocus
num = Me.numpages.value 'Aqui está o problema: se maior que 1, só recebe o valor "zero", apesar de o controle [numpages] mostrar sempre o valor correto
Me.Refresh
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
If num = 0 ou num = 1 Then 'existindo um único registro ou nenhum no SubForm, passa para o próximo registro do Form principal
Me!CmdoNF.SetFocus
Me!numpages.SetFocus
Me.Refresh
DoCmd.GoToRecord , , acNext
Else 'existindo mais de 2 registros no SubForm, deveria varrer os registros do SubForm
For pag = 1 To (num - 1)
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
DoCmd.GoToRecord , , acNext
Me![F-Em].SetFocus
Me![F-Em]!Comando262.SetFocus
Next pag
End If
If Not tt = TotalRegistrosFormPrincipal Then
Exit Sub
Else
Goto Início
End If
End Sub
Qualquer ajuda será bem-vinda.
Obrigado pela atenção de todos.
EA