• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

nokPT

Passou-se, está a apagar valores sem motivo

13 mensagens neste tópico

Estou a desenvolver um programa de registo de valores.

Como era urgente a sua implementação, estou a registar os valores em ficheiro csv, um por dia com 1760 linha (1 por minuto).

Quando o programa arranca, lê (dos ficheiros) todos os dados relativos ao ano corrente, e a partir daí actualiza o minuto actual com dados provenientes de um OPC Server e calcula os valores da hora, dia e mês.

Para isso criei 4 arrays:

    Friend DadosMinuto(1 + 12, 1 + 31, 24, 60) As stuDados
    Friend DadosHora(1 + 12, 1 + 31, 24) As stuDados
    Friend DadosDia(1 + 12, 1 + 31) As stuDados
    Friend DadosMes(1 + 12) As stuDados

O utilizador tem a hipótese de consultar em qualquer momento os valores do Dia, Mês ou Ano em 3 forms diferentes.

Estava a funcionar muito bem, até hoje ter percebido que não estava a permitir ao utilizador a consulta de anos anteriores, então criei mais 4 arrays:

    Dim HistóricoMinuto(1 + 12, 1 + 31, 24, 60) As frmMain.stuDados
    Dim HistóricoHora(1 + 12, 1 + 31, 24) As frmMain.stuDados
    Dim HistóricoDia(1 + 12, 1 + 31) As frmMain.stuDados
    Dim HistóricoMes(1 + 12) As frmMain.stuDados

e se o ano que o utilizador for o actual faço:

                HistóricoMinuto = frmMain.DadosMinuto
                HistóricoHora = frmMain.DadosHora
                HistóricoDia = frmMain.DadosDia
                HistóricoMes = frmMain.DadosMes

Se não for, leio para o HistóricoXXX os valores relativos ao ano, calculo etc...

O problema!

Se o utilizador escolher um ano sem valores, naturalmente que o HistóricoXXX fica a zero, mas os DadosXXX também, já  :wallbash: e não encontro a justificação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não percebo, estou farto de  :wallbash:

Tenho 4 forms criadas.

Na form principal crio os arrays principais com Friend que são carregado no arranque do programa e actualizados periodicamente.

Depois criei em cada form de consulta crio novos array como Private.

Quando corro a rotina e ponho os arrays da form de consulta a zero -> fico com os array principais a zero (entretanto depois continuam a ser actualizados, mas os dados anteriores já eram)

Não consigo perceber o que se está a passar.

Já mudei os nomes da variáveis, já não sei o que fazer mais.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Arrays para tanta informação!

Porque não usas uma DataTable() em vez de arrays ? Podes carregar as colunas que queres e é simples de filtrar usando um DataView.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se a ideia é teres as arrays acessíveis anytime anywhere porque não as declaras num módulo ?  :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Arrays para tanta informação!

Porque não usas uma DataTable() em vez de arrays ? Podes carregar as colunas que queres e é simples de filtrar usando um DataView.

Mas eu não quero filtrar.

A ideia é criar um DataLog e registar vários valores de minuto a minuto, para depois fazer alguns cálculos: para alguns valores é uma soma de tempo para outros é uma média do valor e para outros é uma soma de tempo em que a média do valor este a cima de um setpoint.

É verdade que os arrays são grandes, cada hora tem 60 minutos, cada dia tem 24 horas, cada mês tem 31 dias e o ano tem 12 meses.

Quando o cliente só quer ver o histórico do dia, só necessito minutos e horas, mas quando o cliente quer ver o histórico do ano tenho que ter os dados todos, apesar de só apresentar 12 linhas correspondentes aos 12 meses.

O problema é quando faço:

A=B

estou a passar o valor de B para A, isto é claro.

Só que não sei o porque, se no momento seguinte se fizer:

A=0

então também fico com:

B=0 (sem haver nenhuma instrução para isso)

e isto não faz sentido.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se a ideia é teres as arrays acessíveis anytime anywhere porque não as declaras num módulo ?  :thumbsup:

Ok, declarei na form principal, e as privadas em modulos ou forms secundárias, mas porque foi crescendo assim, nunca tinha pensado nisso, é capaz de ser boa política em questões de organização.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mostra lá como registas os valores no array e como utilizas depois ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não sei se percebi a pergunta:

Crio o array principal assim:

Public Class frmMain
    ' Criação das estruturas
    Structure stuDados
        ' Estrutura dos dados recolhidos do autómato (tempos + valores actuais)
        Dim Ligado As Long
        Dim Funcionamento As Long
        Dim Emissão As Single
        Dim Concentração As Single
    End Structure

' ...

    Friend DadosMinuto(1 + 12, 1 + 31, 24, 60) As stuDados

Noutro módulo (de comunicação)

Transfiro os dados actuais para o array assim:

            frmMain.DadosMinuto(Now.Month, Now.Day, Now.Hour, Now.Minute).Emissão = TagsAutómato(0).Analog.AIT520.Value
            frmMain.DadosMinuto(Now.Month, Now.Day, Now.Hour, Now.Minute).Concentração = TagsAutómato(0).Analog.CO510.Value

Noutro módulo (relatórios ou histórico)

Crio um array assim:

 Private HistóricoMinuto(1 + 12, 1 + 31, 24, 60) As frmMain.stuDados

e a sseguir copio os valores de um para o outro e faço os cálculos todos com o array privado HistóricoMinuto:

    Private Sub CarregarValores()
        Try
            HistóricoMinuto = frmMain.DadosMinuto
            If dtpValores.Value.Year <> Now.Year Then
                ' 1º Limpa os valores actuais
                For mes As Integer = 1 To 12
                    For dia As Integer = 1 To 31
                        For hora As Integer = 0 To 23
                            For minuto As Integer = 0 To 59
                                HistóricoMinuto(mes, dia, hora, minuto).Concentração = 0
                                HistóricoMinuto(mes, dia, hora, minuto).Emissão = 0
                                HistóricoMinuto(mes, dia, hora, minuto).Funcionamento = 0
                                HistóricoMinuto(mes, dia, hora, minuto).Ligado = 0
                            Next
                            HistóricoHora(mes, dia, hora).Concentração = 0
                            HistóricoHora(mes, dia, hora).Emissão = 0
                            HistóricoHora(mes, dia, hora).Funcionamento = 0
                            HistóricoHora(mes, dia, hora).Ligado = 0
                        Next
                    Next
                Next

                ' 2º carrega os valores a partir do disco
                For Mes As Integer = 1 To 12
                    For Dia As Integer = 1 To 31
                        Dim filename As String = MainPath & "Valor\" & dtpValores.Value.Year.ToString & Format(Mes, "00") & Format(Dia, "00") & ".csv"
                        If My.Computer.FileSystem.FileExists(filename) = True Then
                            Dim Ficheiro As New System.IO.StreamReader(filename)
                            Dim Linha As String
                            Dim Valores() As String
                            Linha = Ficheiro.ReadLine ' A 1ª linha é´o cabeçalho (é lixo)
                            For hora As Integer = 0 To 23
                                For Minuto As Integer = 0 To 59
                                    Linha = Ficheiro.ReadLine
                                    Valores = Linha.Split(";") ' Delimeter
                                    HistóricoMinuto(Mes, Dia, hora, Minuto).Ligado = Valores(1)
                                    HistóricoMinuto(Mes, Dia, hora, Minuto).Funcionamento = Valores(2)
                                    HistóricoMinuto(Mes, Dia, hora, Minuto).Emissão = Valores(3)
                                    HistóricoMinuto(Mes, Dia, hora, Minuto).Concentração = Valores(4)
                                Next
                            Next
                            Ficheiro.Close()
                        End If
                    Next
                Next

                ' 3º Calcula os valores
                For Mes As Integer = 1 To 12
                    For Dia As Integer = 1 To 31
                        For Hora As Integer = 0 To 23
                            For Minuto As Integer = 0 To 59
                                ' Cálculo do relatório diário (de hora a hora)
                                HistóricoHora(Mes, Dia, Hora).Ligado = HistóricoHora(Mes, Dia, Hora).Ligado + HistóricoMinuto(Mes, Dia, Hora, Minuto).Ligado ' Total de minutos
                                HistóricoHora(Mes, Dia, Hora).Funcionamento = HistóricoHora(Mes, Dia, Hora).Funcionamento + HistóricoMinuto(Mes, Dia, Hora, Minuto).Funcionamento ' Total de minutos
                                HistóricoHora(Mes, Dia, Hora).Emissão = HistóricoHora(Mes, Dia, Hora).Emissão + HistóricoMinuto(Mes, Dia, Hora, Minuto).Emissão
                                HistóricoHora(Mes, Dia, Hora).Concentração = HistóricoHora(Mes, Dia, Hora).Concentração + HistóricoMinuto(Mes, Dia, Hora, Minuto).Concentração
                            Next
                            HistóricoHora(Mes, Dia, Hora).Emissão = HistóricoHora(Mes, Dia, Hora).Emissão / 60 ' Média
                            HistóricoHora(Mes, Dia, Hora).Concentração = HistóricoHora(Mes, Dia, Hora).Concentração / 60 ' Média
                        Next
                    Next
                Next
            End If
        Catch ex As Exception
            GravaErro("Erro #16 -> frmValoresDiários -> " & ex.Message)
        End Try
    End Sub

Nunca mais uso o array principal, mas fico sempre com ele a zero

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não percebi o que se estava a passar, mas já dei a volta.

Uma vez que estou a consultar um histórico, passei a ler os valores todos a partir do disco para o histórico, acabei assim o copiar os valores de um array para o outro e ficou a funcionar (com a desvantagem de ficar ligeiramente mais lento)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Encontrei um artigo em:

http://visualbasic.about.com/b/2005/10/29/when-is-a-copy-not-a-copy.htm

Que explica que em .NET, quando se copia um array, não se está a copiar os dados apenas a estrutura e que os dados de um array ficam referenciados ao outro, ou seja, quando apago 1 array, estou na realidade (via referência) a apagar o outro array.

A solução é fazer um clone:

ArrayDestino = ArrayOriginal.clone

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu ainda não entendi muito bem porque estás a usar arrays e sinceramente não me parece um método nada seguro ou prático.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porque para já, tenho uma quantidade substancial de dados.

Porque com o array é fácil de organizar os dados e é fácil de aceder e perceber

Por exemplo:

HistóricoMinuto(mes, dia, hora, minuto)

São dados raw, sem serem tratados, são dados internos que depois vou calcular e apresentar os resultados

Depois para cada array tenho várias variáveis:

HistóricoMinuto(mes, dia, hora, minuto).Concentração

HistóricoMinuto(mes, dia, hora, minuto).Emissão

HistóricoMinuto(mes, dia, hora, minuto).Funcionamento

HistóricoMinuto(mes, dia, hora, minuto).Ligado

HistóricoMinuto(mes, dia, hora, minuto).EmAlarme

Acho que com uma DataTable seria mais complicado, ou não se calhar.

Mas é capaz de comer mais recursos que um array, não?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem, sinceramente nunca tentei usar uma DataTable com um GRANDE número de registos, mas que é muito mais simple de manipular, lá isso é.

Podes carregar a informação muito facilmente e filtrar pelo que queres (por qualquer campo), incluindo datas.

Vê este exemplo:

        ' Cria uma DataTable
        Dim dt As New DataTable("Teste")
        dt.Columns.Add("id", GetType(Byte)).AutoIncrement = True
        dt.Columns.Add("data", GetType(DateTime))
        dt.Columns.Add("campo1", GetType(String))
        dt.Columns.Add("campo2", GetType(String))
        dt.Columns.Add("campo3", GetType(Integer))

        Dim dr As DataRow = Nothing
        For x As Int16 = 0 To 999
            dr = dt.NewRow
            dr("data") = Now.AddDays(1)
            dr("campo1") = "C1_" & x.ToString.PadLeft(3, "0"c)
            dr("campo2") = "C2_" & x.ToString.PadLeft(3, "0"c)
            dr("campo3") = x
            dt.Rows.Add(dr)
        Next


        Stop ' DataTable criada e preenchida

        ' Filtra os resultados
        Dim dv As DataView = dt.DefaultView
        dv.RowFilter = String.Format("id <= 10 ")

        ' Mostra os resultados filtrados
        For Each row As DataRowView In dv
            Dim result As String = _
                    String.Format("ID:{0} Data:{1} Campo1:{2} Campo2:{3} Campo3:{4}", _
                    row.Item(0), row.Item(1), row.Item(2), row.Item(3), row.Item(4))
            Debug.WriteLine(result)
        Next

Precisas de filtrar os dados depois ? Também podias pensar um POO, porque sinceramente não gosto muito de usar arrays dessa forma. São faliveis, são muito lentos caso necessites de fazer um Redim, etc.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora