Ir ao conteúdo
  • Cadastre-se

Midori

Membro Pleno
  • Posts

    3.542
  • Cadastrado em

  • Última visita

posts postados por Midori

  1. Está funcionando o envio com MailEnvelope e não com os objetos do MS Outlook. É o que acontece com ActiveSheet.MailEnvelope.Item.Send.

     

    Na documentação do MailEnvelope não vi um membro para adicionar anexos. Para isso, a partir do Excel, você pode usar os objetos do MS Outlook mesmo em vez de MailEnvelope e acredito que já tenha acrescentado a referência já que o código não tem CreateObject para o Outlook.

     

    Aqui no fórum tem exemplos de como enviar email assim, veja se este ajuda,

     

     

  2. 2 horas atrás, Zamboni_du disse:

    Set xMail = Application.ActiveInspector.CurrentItem <- linha onde está apresentando o Erro

    Esse erro acontece quando não há nenhum item/objeto para referenciar no seu ambiente. O item é a janela do MS Outlook da opção Novo Email. Você pode abrir essa janela manualmente antes de rodar a macro ou criar assim,

     

    Set xMail = Application.CreateItem(olMailItem)
    xMail.Display

     

    A nova atribuição para xMail.

  3. Para facilitar o desenvolvimento, antes de partir para a leitura do arquivo, você pode iniciar as structs com as coordenadas como a do exemplo para testar o returno da função.

     

    Se visualizar a matriz para o cálculo da determinante desta forma, acho que fica mais simples,

    Ax Ay 1 | Ax Ay
    Bx By 1 | Bx By
    Cx Cy 1 | Cx Cy

     

    Aí é só fazer as operações, p.ex: float det = A.x * B.y + A.y * C.x...

     

    • Obrigado 1
  4. A função PROCV não é a mais adequada para esse caso porque no array da busca também vai o range das colunas com o retorno. Porém com PROCX é possível aplicar uma formatação simples no array da busca, já que a função oferece os parâmetros dos arrays de busca e retorno, p.ex,

     

    =PROCX(ARRUMAR(G$4)&$F5;TEXTO($A$2:$A$14;"mmmaaaa");$D$2:$D$14;0;0)

     

    Veja que a função TEXTO faz a formatação que possibilita a busca passada para o primeiro argumento que concatena o mês com o ano. O uso de ARRUMAR foi para remover o espaço, vi que há esse tipo de ocorrência.

  5. Tenho um projeto para o ambiente X envolvendo movimentos com particulas. Esse por enquanto é um caso de controlar a direção, colisoes nas bordas entre particulas, etc. Ainda quero criar mais funções com relações físicas como uma particula caindo, considerando a gravidade, enquanto ganha aceleração durante a queda e quica até parar.

     

    Para este código tem coisas que preciso melhorar, no anexo p.ex dá para ver que acontece casos de sobreposição.

     

    O código para quem se interessar ou quiser fazer sugestões ou melhorias.

     

    Para compilar estes links para as libs do Motif e X11 são necesários:  -lXm -lXt -lXext -lX11

     

    forum.png.af67a7935eef25d9b89cea3a712bdf83.png

     

     

    #include <X11/X.h>
    #include <X11/Xlib.h>
    #include <X11/extensions/Xdbe.h>
    #include <Xm/Xm.h>
    #include <Xm/DrawingA.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    
    #define DEFAULT_WIDTH   300
    #define DEFAULT_HEIGHT  300
    #define DEFAULT_PART    3
    #define	MAX_PART        50
    
    #define RAND(max) (rand() % (max))
    #define RGB(r, g, b) ((r) * 65536 + (g) * 256 + (b))
    
    static XdbeBackBuffer   buffer;
    static Display*         display;
    static Window           window;
    static GC               gc;
    static Dimension        width;
    static Dimension        height;
    
    typedef struct{
        double x;
        double y;
    }Point;
    
    typedef struct{
        Point   position;
        Point   velocity;
        Point   acceleration;
        int     radius;
        double  mass;
        long    color;
    }Particle;
    
    XtAppContext init_app(int* argc, char* argv[]);
    Particle* alloc_particles(int count);
    Bool event_app(XtAppContext app);
    Particle* draw(Particle* particle);
    Particle* collision(Particle* particle, int count);
    Particle* move(Particle* particle, int count);
    
    int main(int argc, char* argv[]){
        int opt;
        int count = DEFAULT_PART;
        width = DEFAULT_WIDTH;
        height = DEFAULT_HEIGHT;
    
        while((opt = getopt(argc, argv, "w:h:c:")) != -1){
            switch(opt){
                case 'h':
                    height = atoi(optarg);
                    break;
                case 'w':
                    width = atoi(optarg);
                    break;
                case 'c':
                    count = atoi(optarg);
                    break;
            }
        }
    	
        if(count < 1 || count > MAX_PART){
            fprintf(stderr, "Error, count cannot be < 1 or > %d\n", MAX_PART);
            exit(1);
        }
    	
        XtAppContext app = init_app(&argc, argv);
    	
        if(app != NULL){
            srand(time(NULL));
            Particle* particle = alloc_particles(count);
    		
            if(particle != NULL){
                while(event_app(app) == False){
                    move(particle, count);				
                }
                free(particle);
            }else{
                fprintf(stderr, "Cannot alloc particle\n");
                exit(1);
            }		
        }else{
            fprintf(stderr, "Invalid %dx%d dimension\n", width, height);
            exit(1);
        }
        return 0;
    }
    
    /******************************************************************************
     *  - operações basicas do Motif/X11 para criar o ambiente.
     *  - AppClass: xparticle (shell-widget) e area (area-widget)
     *  - Chama funcao para alocar o buffer onde as particulas serao diretamente
     *      criadas. Metodo para evitar XClearWindow com efeito flickering
     *      na atualizacao da janela para os movimentos das particulas.
     *****************************************************************************/
    XtAppContext init_app(int* argc, char* argv[]){
        XtAppContext    app;
        Widget          shell;
        Widget          area;
        Dimension       display_width;
        Dimension       display_height;
    	
        shell = XtVaAppInitialize(&app, "xparticle", NULL, 0, argc, argv, NULL, NULL);
        XtVaSetValues(shell, XmNtitle, "Particle Collision", XmNwidth, width, XmNheight, height, NULL);
        area = XtVaCreateManagedWidget("area", xmDrawingAreaWidgetClass, shell, NULL);
        display = XtDisplay(area);
        display_width = DisplayWidth(display, DefaultScreen(display));
        display_height = DisplayHeight(display, DefaultScreen(display));
    	
        if(width > display_width || width < DEFAULT_WIDTH 
            || height > display_height || height < DEFAULT_HEIGHT){
                return NULL;
        }	
    
        gc = XCreateGC(display, RootWindowOfScreen(XtScreen(area)), 0, NULL);
        XtRealizeWidget(shell);
        window = XtWindow(area);
        XSelectInput(display, window, KeyPressMask);
        buffer = XdbeAllocateBackBufferName(display, window, XdbeBackground);	
        return app;
    }
    
    /******************************************************************************
     * - Atribui valores aleatorios a estrutura da particula alocada dinamicamente
     * - Aceleracao ainda com valor neutro para o calculo da posicao em move
     * - Ainda sem teste de sobreposicao e relação de raio-quantidade-dimensoes 
     *****************************************************************************/
    Particle* alloc_particles(int count){
        Particle*	particle = (Particle*)malloc(sizeof(Particle) * count);
    	
        if(particle != NULL){
            for(int i = 0; i < count; i += 1){
                Particle* A = &particle[i];
                A->radius = RAND(40) + 5;
                A->position.x = RAND(width - A->radius);
                A->position.y = RAND(height - A->radius) + A->radius + 1;
    			
                if(A->position.x < A->radius) A->position.x = A->radius + 1;
                if(A->position.y < A->radius) A->position.y = A->radius + 1;
    			
                A->velocity.x = (RAND(95) + 5)/100.0;
                A->velocity.y = (RAND(95) + 5)/100.0;
                A->mass = A->radius;
                A->acceleration.x = A->acceleration.y = 1;
                A->color = RGB(RAND(128), RAND(128), RAND(128));
            }
        }
        return particle;
    }
    
    /*****************************************************************************
     * - Funcao Bool testa a entrada da tecla q que marca a saida da aplicacao
     * - Chama as funcoes Event.
     * - Chama a funcao XSendEvent:
     *  para Exposure para realizar o movimento da particula durante o loop de main
     ****************************************************************************/
    Bool event_app(XtAppContext app){
        XEvent	event;
    	
        XtAppNextEvent(app, &event);
        XtDispatchEvent(&event);		
    	
        if(event.type == KeyPress){
            if(XLookupKeysym(&event.xkey, 0) == XK_q){
                return True;
            }
        }
        XSendEvent(display, window, 1, ExposureMask, &event);
        return False;
    }
    
    /******************************************************************************
     *  - Atribui a cor e desenha particula com X*Arc.
     *  - O angulo inicia o desenho do arco a partir do "horario" 3 no sentido
     *      anti-horario. A posicao/coordenada x/y não fica centralizada.
     *  - A operacao 360 * 64 e padrão para o ultimo argumento para criar o circulo
     *  - correção feita com operações no raio para acertar/centralizar a posicao
     *****************************************************************************/
    Particle* draw(Particle* particle){
        XSetForeground(display, gc, particle->color);
        XFillArc(display, buffer, gc, 
            particle->position.x - particle->radius, 
            particle->position.y - particle->radius,
            particle->radius * 2,
            particle->radius * 2,
            0, 360 * 64);
        return particle;
    }
    
    /******************************************************************************
     * - Bloco For removido do loop da funcao move. 
     * - Testa a particula "atual" (count recebida do indice i de move) e as demais.
     * - Atualiza a velocidade e direcao x/y apos a colisao
     *****************************************************************************/
    Particle* collision(Particle* particle, int count){
        Particle* A = &particle[count];
    	
        for(int i = 0; i < count; i += 1){
            Particle* B = &particle[i];
    		
            double dx = A->position.x - B->position.x;
            double dy = A->position.y - B->position.y;
            double area = dx * dx + dy * dy;
    		
            if(area <= A->radius * A->radius + B->radius * B->radius){
                double dot = 
                    dx * (B->velocity.x - A->velocity.x)
                    + dy * (B->velocity.y - A->velocity.y);
    
                if(dot > 0){
                    double sx = dx * dot / area;
                    double sy = dy * dot / area;
                    double aweight = 2 * B->mass/(A->mass + B->mass);
                    double bweight = 2 * A->mass/(A->mass + B->mass);
    
                    A->velocity.x += aweight * sx;
                    A->velocity.y += aweight * sy;
                    B->velocity.x -= bweight * sx;
                    B->velocity.y -= bweight * sy;
                }
            }
        }
        return A;
    }
    
    /******************************************************************************
     * - O loop seleciona as particulas com seus respectivos valores, testa as
     *  colisoes, desenha no buffer e aplica a substituicao pela area/janela.
     *****************************************************************************/
    Particle* move(Particle* particle, int count){
        XdbeSwapInfo    swinfo = {window, XdbeBackground};
    	
        for(int i = 0; i < count; i += 1){
            Particle* A = collision(particle, i);
            draw(A);
    
            if(A->position.x < A->radius || A->position.x > width - A->radius){
                A->velocity.x = -A->velocity.x;
            }
    		
            if(A->position.y < A->radius || A->position.y > height - A->radius){
                A->velocity.y = -A->velocity.y;
            }
    		
            A->position.x += A->velocity.x * A->acceleration.x;
            A->position.y += A->velocity.y * A->acceleration.y;
        }
        XdbeSwapBuffers(display, &swinfo, 1);
        return particle;
    }

     

    Para o cálculo que apliquei na função collision, crédito para uma resposta do user desta página,

     

    https://gamedev.stackexchange.com/questions/20516/ball-collisions-sticking-together

    • Curtir 2
    • Obrigado 1
  6. A melhoria pode ser na questão da velocidade fazendo como comentei, p.ex,

     

    Sub ExcUlt180dias()
        Dim Area    As Range
        Dim Coluna  As Range
        Dim Linha   As Long
        Dim Conta   As Long
        
        Set Area = [B5:N204]
        Set Coluna = Area.Columns(8)
        Conta = WorksheetFunction.CountIf(Coluna, "<=180")
        
        If Conta > 0 Then
            Linha = Coluna.Rows.Count - Conta
            Call Area.Sort(Coluna, xlDescending)
            Call Area.Rows(Linha + 1).Resize(Conta).Clear
            Call MsgBox(Conta & " registros excluídos", vbInformation)
        End If
    End Sub

     

  7. É quase isso, só faltou atribuir o valor.

     

    Assim seu código está testando uma variável com o valor sempre zero já que no VBA esse é o padrão para as numéricas.

     

    Declare Valor, sugiro Long, e faça a atribuição antes do If, assim: Valor = Area(Linha).Value.

     

    De qualquer forma não devia acontecer erro. Mostre a mensagem que aparece caso continue.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...