
Frank K Hosaka
Membros-
Total de itens
1.532 -
Registro em
-
Última visita
Tudo que Frank K Hosaka postou
-
Depois de atualizar o Laravel Installer fica bem mais fácil colocar o Laravel 12 no notebook, o problema é que ele pede para escolher uma extensão (React, Vue, LiveWire) ou nenhum. O problema do Laravel puro é que ele não tem uma rotina para o login, assim eu não tive outra escolha senão selecionar uma extensão, no meu caso foi o LiveWire. Após terminar a instalação, o Laravel manda você direto para a tela do 'dashboard' se passar pela rotina do login, é uma tela bonita, mas eu não tenho a menor ideia de como trabalhar com ela. Eu só sei trabalhar com texto, e assim eu tenho o meu 'menuView'. Eu encontrei a rotina do login, e eu alterei assim: arquivo app > Livewire > Auth > Login.php (listagem parcial) <?php //... class Login extends Component { //... public function login(): void { $this->validate(); $this->ensureIsNotRateLimited(); if (! Auth::attempt(['email' => $this->email, 'password' => $this->password], $this->remember)) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages(['email' => __('auth.failed'),]); } RateLimiter::clear($this->throttleKey()); Session::regenerate(); $this->redirectIntended(default: route('menuView', absolute: false), navigate: true); } //... } Fiz logoff, entrei de novo, mas acabei de cara com o 'dashboard'. Então, decidi fechar o navegador, e pedi para o VS Code executar composer dump-autoload, e só assim é que consegui chegar no menuView, depois da rotina do login.
-
Criei um novo projeto para conhecer o Laravel 12, e acabei me perdendo. A tela de boas vindas mudou, só tem dois botões. Um fala sobre a documentação do Laravel 12 e outro é Deploy, e ele me mandou para o Laravel Cloud, onde eu abri a minha conta, e depois fiquei sem saber o que fazer. Procurei o YouTube, e ele não me ajudou em nada, o vídeo falava da época em que o pessoa pretendia atualizar o Laravel. Assim, eu tive que improvisar. Procurei o Laravel 11, e de lá eu instalei o Breeze Blade (isso não existe no Laravel 12); e assim eu consegui colocar a opção de login na tela de boas vindas e cheguei no painel de controle. Pelo que pude deduzir o Laravel 12 é para quem tem o código hospedado no Github, mas por enquanto vou continuar usando o meu notebook. Na minha opinião, o pessoal precisa colocar um tutorial de como usar o Laravel 12, não adianta mandar eu ler os conceitos básicos do Laravel que eu vou acabar dormindo. ============================================== No fórum do Laracasts encontrei a solução: https://laracasts.com/discuss/channels/laravel/add-livewire-starter-kit-to-existing-base-laravel-12-installation A primeira tarefa é atualizar o instalador do Laravel assim: composer global remove laravel/installer composer global require laravel/installer Em seguida, você usa o comando: laravel new novoProjeto Ele vai fazer uma série de perguntas, uma delas é starter kit, eu escolhi o LiveWire, apesar de não ter a menor ideia de como usar isso, e também tem um outro tanto de perguntas que fui respondendo de acordo com o meu nariz, e assim ele já embutiu a rotina de login no projeto. Como eu trabalho com mysql, eu alterei o arquivo .env. Durante dois dias fiquei batendo a cabeça na parede, mas hoje eu vi que o Laravel 12 é muito mais fácil de instalar. Eles mudaram o script para executar o código no computador local, você não precisa mais ter dois terminais, um para ativar o servidor e outro para ativar o vite, agora faz as duas tarefas com o comando composer run dev
-
Nessa semana, eu consegui fazer o cálculo do Simples Nacional no meu notebook, mas eu não consegui fazer o valor do imposto ser igual ao que foi calculado pela Contabilidade, a diferença é de alguns centavos, mas eu posso usar o meu programa como uma estimativa. O problema foi na hora de copiar o meu código PHP na Hostinger, lá o PHP reclamou que o comando scandir não encontrou o diretório que mandei procurar. Levei um tempão para entender porque o scandir não funciona: o que funciona no notebook nem sempre vai funcionar na Hostinger. Na base da tentativa e erro, fui procurar a solução no HTML, no <input type="file" multiple>, mas o máximo que eu consegui foi obter uma lista de 20 arquivos, quando precisava ver coisa da ordem de 700 arquivos. O Copilot explicou que o navegador e o servidor podem definir restrição para o <input type="file" multiple>, e o Copilot disse que eu preciso estudar mais, ir além do PHP e aprender como fazer a Hostinger ter acesso remoto ao meu notebook, e assim calcular o Simples Nacional na internet. A minha primeira tentativa de calcular o Simples foi pelo comando zipArchive do PHP, e eu consegui fazer funcionar uma vez ou outra. O Windows sempre consegue abrir o arquivo .zip, já o comando zipArchive do PHP sempre reclamava que encontrou erro no arquivo, assim eu desisti dele. Conclusão: eu não sei se é possível calcular o Simples Nacional na internet, mas eu consegui calcular aqui no notebook com o PHP. Mas para calcular o Simples aqui no notebook, eu preciso da venda dos doze últimos meses que está no MySQL que está hospedado lá na Hostinger. Isso é constrangedor, mas pelo menos eu posso chorar a vontade, isso é o que dá para fazer quando estou num beco sem saída. bling.php (parcial) <?php class Bling { static function simplesSelecionado() { $diretorio="C:/Users/Frank/Downloads/".substr($_FILES['pasta']['full_path'],0,-4); $contaArquivos = count(scandir($diretorio)) - 2 - 2 ; $notasFiscais = []; $nfCanceladas = []; $nfces = scandir($diretorio); $notasCanceladas=0; $somaTotal=0; $comST=0; $semST=0; foreach($nfces as $nfce) { if($nfce !== '.' && $nfce !=='..' ) { if(strpos($nfce,'-can') !== false) { $nfCanceladas[] = intval(substr($nfce,28,6)); $notasCanceladas++; continue; } $numeroNota=intval(substr($nfce,28,6)); if(in_array($numeroNota,$nfCanceladas)) { continue; } $notasFiscais[]=$numeroNota; $dom = new DOMDocument(); $dom->load("$diretorio/$nfce"); $nfe=$dom->documentElement; if($nfe->getElementsByTagName('vNF')->item(0)) { $somaNF=$nfe->getElementsByTagName('vNF')->item(0)->nodeValue; $somaTotal+=$somaNF; $produtos=$nfe->getElementsByTagName('prod'); foreach($produtos as $p) { $cfop=$p->getElementsByTagName('CFOP')->item(0)->nodeValue; $vProd=$p->getElementsByTagName('vProd')->item(0)->nodeValue; $vDesc=0; if($p->getElementsByTagName('vDesc')->item(0)) { $vDesc=$p->getElementsByTagName('vDesc')->item(0)->nodeValue; } if($cfop==5405) { $comST += $vProd - $vDesc; } else { $semST += $vProd - $vDesc; } } } } } sort($notasFiscais); $primeiraNota=intval($notasFiscais[0]); $ultimaNota=intval($notasFiscais[$contaArquivos-1]); $totalDeNotas=count($notasFiscais); $rendas=bd::x('select * from tbrendabruta order by id desc limit 13')->get(); $renda=0; foreach($rendas as $key=>$r) { if($key>0) { $renda += $r->renda; } } // indices da primeira faixa da tabela do Simples Nacional 2025 no comércio $aliqICMS=1.36; $ICMS=round($semST*$aliqICMS/100,2); $aliqIRPJ=0.22; $IRPJ=round($somaTotal*$aliqIRPJ/100,2); $aliqCSLL=0.14; $CSLL=round($somaTotal*$aliqCSLL/100,2); $aliqCOFINS=0.5096; $COFINS=round($somaTotal*$aliqCOFINS/100,2); $aliqPIS=0.1105; $PIS=round($somaTotal*$aliqPIS/100,2); $aliqINSS=1.66; $INSS=intval($somaTotal*$aliqINSS)/100; $aliqSimples=4; $Simples=$ICMS+$IRPJ+$CSLL+$COFINS+$PIS+$INSS; view('blingSimples',['primeiraNota'=>$primeiraNota,'ultimaNota'=>$ultimaNota, 'notasFiscais'=>$notasFiscais,'somaTotal'=>$somaTotal, 'contaArquivos'=>$contaArquivos,'notasCanceladas'=>$notasCanceladas, 'totalDeNotas'=>$totalDeNotas,'nfCanceladas'=>$nfCanceladas, 'comST'=>$comST,'semST'=>$semST,'renda'=>$renda, 'aliqICMS'=>$aliqICMS,'ICMS'=>$ICMS, 'aliqIRPJ'=>$aliqIRPJ,'IRPJ'=>$IRPJ, 'aliqCSLL'=>$aliqCSLL,'CSLL'=>$CSLL, 'aliqCOFINS'=>$aliqCOFINS,'COFINS'=>$COFINS, 'aliqPIS'=>$aliqPIS,'PIS'=>$PIS, 'aliqINSS'=>$aliqINSS,'INSS'=>$INSS, 'aliqSimples'=>$aliqSimples,'Simples'=>$Simples, 'rendas'=>$rendas]); } } arquivo blingSimples.php (ele usa o CSS https://cdn.tailwindcss.com) <?php include 'menuView.php'; ?> <script>btMenu.innerHTML="Simples";document.title="Simples"</script> <div class=flex> <div>Total de Notas</div> <div class="ml-2"><?=$totalDeNotas?></div> </div> <div class=flex> <div>Notas Canceladas</div> <div class="ml-2 text-right mr-2"><?=$notasCanceladas.": ";?></div> <?php foreach($nfCanceladas as $n): echo $n."<br>"; endforeach; ?> </div> <div class=flex> <div>Total das Notas Fiscais</div> <div class="text-right ml-2"><?=dec($somaTotal)?></div> </div> <div class=flex> <div>Primeira Nota</div> <div class="text-right ml-2"><?=$primeiraNota?></div> </div> <div class=flex> <div>Última Nota</div> <div class="text-right ml-5"><?=$ultimaNota?></div> </div> <div class=flex> <div class="w-[120px]">Renda 12 Meses</div> <div class="w-[100px] text-right"><?=dec($renda)?></div> </div> <div class="flex"> <?php $contador = 0; foreach($rendas as $key=>$r): if($key>0): if ($contador % 4 === 0 && $contador !== 0): ?> </div><div class="flex"> <?php endif; ?> <div class="w-[50px]"><?php echo $r->apuracao; ?></div> <div class="w-[80px] text-right font-semibold mr-2"><?php echo dec($r->renda); ?></div> <?php $contador++; endif; endforeach; ?> </div> <div class=flex> <div class="w-[120px]">Com ST</div> <div class="w-[100px] text-right"><?=dec($comST)?></div> </div> <div class=flex> <div class="w-[120px]">Sem ST ICMS</div> <div class="w-[100px] text-right"><?=dec($semST)?></div> <div class="w-[100px] text-right"><?=dec($aliqICMS)."%"?></div> <div class="w-[100px] text-right"><?=dec($ICMS)?></div> </div> <div class=flex> <div class="w-[120px]">IRPJ</div> <div class="w-[100px] text-right"><?=dec($somaTotal)?></div> <div class="w-[100px] text-right"><?=dec($aliqIRPJ)."%"?></div> <div class="w-[100px] text-right"><?=dec($IRPJ)?></div> </div> <div class=flex> <div class="w-[120px]">CSLL</div> <div class="w-[100px] text-right"><?=dec($somaTotal)?></div> <div class="w-[100px] text-right"><?=dec($aliqCSLL)."%"?></div> <div class="w-[100px] text-right"><?=dec($CSLL)?></div> </div> <div class=flex> <div class="w-[120px]">COFINS</div> <div class="w-[100px] text-right"><?=dec($somaTotal)?></div> <div class="w-[100px] text-right"><?=dec($aliqCOFINS)."%"?></div> <div class="w-[100px] text-right"><?=dec($COFINS)?></div> </div> <div class=flex> <div class="w-[120px]">PIS</div> <div class="w-[100px] text-right"><?=dec($somaTotal)?></div> <div class="w-[100px] text-right"><?=dec($aliqPIS)."%"?></div> <div class="w-[100px] text-right"><?=dec($PIS)?></div> </div> <div class=flex> <div class="w-[120px]">INSS</div> <div class="w-[100px] text-right"><?=dec($somaTotal)?></div> <div class="w-[100px] text-right"><?=dec($aliqINSS)."%"?></div> <div class="w-[100px] text-right"><?=dec($INSS)?></div> </div> <div class=flex> <div class="w-[120px]">Simples</div> <div class="w-[100px] text-right">Estimativa</div> <div class="w-[100px] text-right"><?=dec($aliqSimples)."%"?></div> <div class="w-[100px] text-right font-semibold"><?=dec($Simples)?></div> </div>
-
Comecei a estudar o cálculo do Simples Nacional, começando com um arquivo zipado da Bling, onde tem um monte de NFCE. O problema é a nota cancelada. A nota comum tem o formato 35...123-nfe.xml, já a nota cancelada tem o formato 35...123-can.xml. No Windows Explorer, o arquivo -can aparece antes do -nfe. Usei o famoso método da tentativa e erro e presumi que o comando PHP scandir($diretorio) seguisse o mesmo formato do Windows Explorer. O problema é como desconsiderar o arquivo -can e o arquivo -nfe correspondente. E assim o Copilot me ensinou a usar um novo comando do PHP, o continue. Eu achei esse comando muito esperto, digno de receber uma nota aqui no fórum, o comando continue simplesmente faz o ciclo foreach pular para o item seguinte: <?php class Bling { function faltanteSelecionado() { $diretorio="C:/Users/Frank/Downloads/".substr($_FILES['pasta']['full_path'],0,-4); $contaArquivos = count(scandir($diretorio)) - 2 - 2 ; $notasFiscais = []; $nfCanceladas = []; $nfces = scandir($diretorio); $notasCanceladas=0; $somaTotal=0; $comST=0; $semST=0; foreach($nfces as $nfce) { if($nfce !== '.' && $nfce !=='..' ) { if(strpos($nfce,'-can') !== false) { $nfCanceladas[] = intval(substr($nfce,28,6)); $notasCanceladas++; continue; } $numeroNota=intval(substr($nfce,28,6)); if(in_array($numeroNota,$nfCanceladas)) { continue; } $notasFiscais[]=$numeroNota; $dom = new DOMDocument(); $dom->load("$diretorio/$nfce"); $nfe=$dom->documentElement; if($nfe->getElementsByTagName('vNF')->item(0)) { $somaNF=$nfe->getElementsByTagName('vNF')->item(0)->nodeValue; $somaTotal+=$somaNF; $produtos=$nfe->getElementsByTagName('prod'); foreach($produtos as $p) { $cfop=$p->getElementsByTagName('CFOP')->item(0)->nodeValue; $vProd=$p->getElementsByTagName('vProd')->item(0)->nodeValue; $vDesc=0; if($p->getElementsByTagName('vDesc')->item(0)) { $vDesc=$p->getElementsByTagName('vDesc')->item(0)->nodeValue; } if($cfop==5405) { $comST += $vProd - $vDesc; } else { $semST += $vProd - $vDesc; } } } } } sort($notasFiscais); $primeiraNota=intval($notasFiscais[0]); $ultimaNota=intval($notasFiscais[$contaArquivos-1]); $totalDeNotas=count($notasFiscais); view('blingFaltante',['primeiraNota'=>$primeiraNota,'ultimaNota'=>$ultimaNota, 'notasFiscais'=>$notasFiscais,'somaTotal'=>$somaTotal, 'contaArquivos'=>$contaArquivos,'notasCanceladas'=>$notasCanceladas, 'totalDeNotas'=>$totalDeNotas,'nfCanceladas'=>$nfCanceladas, 'comST'=>$comST,'semST'=>$semST]); } }
-
Ao invés de usar uma caixa de texto, usei uma célula do lado. Se a célula estiver vazia, isso gera erro. Para contornar esse contratempo, o melhor é pedir para o VBA não considerar se a célula estiver vazia, tipo: Sub Teste() If Not IsEmpty(Range("L5").Value) Then Range("K5").Value = Format(Range("L5").Value, "dd,mm,yyyy") Else MsgBox "A célula L5 está vazia. Por favor, insira um valor antes de executar a macro.", vbExclamation, "Aviso" End If End Sub
-
Tentei fazer do seu jeito, insert into meus_contatos (id_contatos,sobrenome) values (null,'frank') e deu certo. Acredito que o problema estava nas aspas, eu tive que mudar um monte de aspas curvas com aspas simples '
-
CREATE TABLE meus_contatos ( id_contatos INT NOT NULL AUTO_INCREMENT PRIMARY KEY, sobrenome VARCHAR(30), primeiro_nome VARCHAR(20), sexo CHAR(1), email VARCHAR(50) UNIQUE, aniversario DATE, profissao VARCHAR(50), locall VARCHAR(50), estado_civil VARCHAR(20), interesses VARCHAR(100), procura VARCHAR(100) ); INSERT INTO meus_contatos (sobrenome, primeiro_nome, sexo, email, aniversario, profissao, locall, estado_civil, interesses, procura) VALUES ('Almeida', 'Jose', 'M', 'jose@gmail.com', '1970-02-02', 'pedreiro', 'brazlandia', 'casado', 'cinema', 'emprego'), ('Prado', 'Joao', 'M', 'joao@gmail.com', '1971-02-02', 'marceneiro', 'brazlandia', 'casado', 'jogos', 'relacionamento'), ('Oliveira Souza', 'Jonas', 'M', 'jonas@gmail.com', '1973-02-02', 'empresario', 'brazlandia', 'casado', 'futebol', 'emprego'), ('Gomes', 'Sergio', 'M', 'sergio@gmail.com', '1979-02-02', 'marceneiro', 'brazlandia', 'solteiro', 'voleibol', 'relacionamento'), ('Gomes', 'Joana', 'F', 'joana@gmail.com', '1980-02-02', 'marceneiro', 'brazlandia', 'casada', 'educacao', 'viagens');
-
Mais uma tentativa: Criei um gráfico e copiei três vezes o mesmo gráfico; criei um userform,um ListBox com nomem lstCharts e um botão com nome cmdApplyBorder, e o código no ambiente do UserForm ficou assim: Private Sub UserForm_Initialize() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("gráficos") Dim cht As ChartObject For Each cht In ws.ChartObjects lstCharts.AddItem cht.Name Next cht ' Define o tamanho da fonte da ListBox lstCharts.Font.Size = 14 End Sub Private Sub cmdApplyBorder_Click() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("gráficos") Dim selectedChart As String selectedChart = lstCharts.Value If selectedChart <> "" Then Dim cht As ChartObject ' Define a borda preta fina para todos os gráficos For Each cht In ws.ChartObjects cht.Border.Color = RGB(0, 0, 0) cht.Border.Weight = xlThin Next cht ' Desenha a borda vermelha mais grossa no gráfico correspondente Set cht = ws.ChartObjects(selectedChart) cht.Border.Color = RGB(255, 0, 0) cht.Border.Weight = xlThick ' Fecha o UserForm Unload Me Else MsgBox "Por favor, selecione um gráfico.", vbExclamation End If End Sub No ambiente de código da planilha gráfico, criei o seguinte comando: Sub ShowUserForm() UserForm1.Show End Sub
-
Não sei se isso vai ajudar, mas eu descobri que fiz uma enorme confusão entre imagem e gráfico, o Copilot me ensinou a criar um gráfico. Primeiro criei uma planilha chamada gráficos, na coluna A1 coloquei Ano, e abaixo dela coloquei 20, 21, 22, 23, 24, 25; na coluna B1 coloquei Popularidade, e abaixo dela coloquei 5, 4, 3, 2, 1, 0. Pedi para o Copilot criar um código VBA (no ambiente da planilha gráficos) e em seguida salvar o arquivo. Isso está longe de resolver o seu problema, mas acredito que ele pode ajudar a conhecer melhor o VBA: Sub CriarEGerarGrafico() Dim ws As Worksheet Dim grafico As ChartObject Dim pastanome As String Dim currentchart As Chart ' Define a planilha onde os dados estão localizados Set ws = Worksheets("gráficos") ' Verifica se já existe um gráfico na planilha e o remove For Each grafico In ws.ChartObjects grafico.Delete Next grafico ' Adiciona um novo gráfico Set grafico = ws.ChartObjects.Add(Left:=100, Width:=375, Top:=50, Height:=225) ' Define a origem dos dados para o gráfico With grafico.Chart .SetSourceData Source:=ws.Range("A1:B6") .ChartType = xlLineMarkers ' Define o tipo de gráfico como linha com marcadores ' Define os títulos do gráfico e dos eixos .HasTitle = True .ChartTitle.Text = "Popularidade ao Longo dos Anos" .Axes(xlCategory, xlPrimary).HasTitle = True .Axes(xlCategory, xlPrimary).AxisTitle.Text = "Ano" .Axes(xlValue, xlPrimary).HasTitle = True .Axes(xlValue, xlPrimary).AxisTitle.Text = "Popularidade" End With ' Salva o gráfico como imagem no mesmo diretório da pasta de trabalho Set currentchart = grafico.Chart pastanome = ThisWorkbook.Path & Application.PathSeparator & "grafico1.gif" currentchart.Export Filename:=pastanome, filtername:="gif" MsgBox "Gráfico criado e salvo com sucesso em: " & pastanome End Sub
-
Hoje, apareceu outro problema, a soma das vendas na Bling deu R$ 15.448,23 mas no PHP deu R$ 15.448,22, ou mais precisamente R$ 15.448,224999. Todas as soluções anteriores não deram certo, hoje tentei uma nova gambiarra: function aint($valor) { return ceil($valor*100)/100; }
-
Copilot: Sim, você pode criar um código VBA para copiar o login e a senha da tabela e colar onde for necessário. Vou fornecer um exemplo de como você pode fazer isso no Excel: ```vba Sub CopiarLoginSenha() Dim ws As Worksheet Dim login As String Dim senha As String Dim link As String Dim destino As Worksheet ' Definir a planilha de origem e a planilha de destino Set ws = ThisWorkbook.Sheets("Planilha1") ' Planilha de origem com os dados Set destino = ThisWorkbook.Sheets("Planilha2") ' Planilha de destino onde os dados serão colados ' Loop através da tabela de dados na Planilha1 For i = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row link = ws.Cells(i, 1).Value login = ws.Cells(i, 2).Value senha = ws.Cells(i, 3).Value ' Exemplo de uso dos dados copiados ' Você pode modificar esta parte para colar os dados onde precisar destino.Cells(i, 1).Value = link destino.Cells(i, 2).Value = login destino.Cells(i, 3).Value = senha ' Mensagem de confirmação MsgBox "Dados do link: " & link & ", login: " & login & " e senha: " & senha & " copiados com sucesso!", vbInformation Next i End Sub ``` Neste exemplo, o código VBA percorre a tabela de dados na "Planilha1" e copia o link, o login e a senha para a "Planilha2". Você pode modificar este exemplo para colar os dados onde for conveniente para o seu caso específico. Para adicionar este código ao seu projeto do Excel: 1. Pressione `Alt + F11` para abrir o Editor do VBA. 2. Clique em `Inserir` > `Módulo` para criar um novo módulo. 3. Copie e cole o código acima no módulo. 4. Feche o Editor do VBA. 5. No Excel, pressione `Alt + F8` para abrir a janela de macros, selecione `CopiarLoginSenha` e clique em `Executar`. Espero que isso ajude! Se precisar de mais alguma coisa, estou aqui para ajudar. 😊
-
Na pasta Controller, eu tenho uma classe chamada Outros, e dentro dele criei o seguinte método: function teste() { return "olá mundo!"; } Na pasta Routes, eu criei uma nova rota no web.php: Route::get('teste',[Outros::class,'teste']); E, finalmente, testei no navegador com o comando localhost:8000/teste e a resposta foi 409 not found. Conversei com o Copilot, e ele disse que 99% dos problemas acontecem por erro de digitação, ele pediu para reiniciar o servidor ("php artisan serve"), e muitas instruções estranhas que decidi não seguir. Usei o velho motor de busca do Google "409 not found" e por sorte o primeiro tópico falava do Laravel. O rapaz disse para usar o comando php artisan route:clear e em seguinda php artisan route:list, e verificar se o novo método está na lista. O Laravel é bacana, mas tem hora que ele me tira do sério.
-
Eu queria debitar duas contas e creditar uma conta, mas não consegui: function teste() { $hoje=date('Y-m-d'); $lcto=tbdiario::max('lcto')+1; tbdiario::insert([ ['dia'=>$hoje,'lcto'=>$lcto,'contad'=>121,'valor'=>87.16], ['dia'=>$hoje,'lcto'=>$lcto,'contad'=>407,'valor'=>1.84], ['dia'=>$hoje,'lcto'=>$lcto,'contac'=>304,'valor'=>89.00] ]); $lcto++; tbdiario::create(['dia'=>$hoje,'lcto'=>$lcto,'contad'=>121,'valor'=>87.16]); tbdiario::create(['dia'=>$hoje,'lcto'=>$lcto,'contad'=>407,'valor'=>1.84]); tbdiario::create(['dia'=>$hoje,'lcto'=>$lcto,'contac'=>304,'valor'=>89.00]); return redirect('diarioInicio'); }
-
<?php class Diario { function historico(Request $request) { if(is_numeric($request->hist)) { if(strpos($request->hist,'.') !== false) { $hist=tbdiario::where('valor',$request->hist) ->orderBy('dia','desc')->get(); } else { $hist=tbdiario::where('lcto',$request->hist) ->orderBy('dia','desc')->get(); } } else { $h=str_replace(' ','%',$request->hist); $hist=tbdiario::where('hist','like',"%$h%") ->orderBy('dia','desc')->get(); } return view('diarioHistorico',['hist'=>$hist]); } }
-
A minha função aint( ) não ajudou muito, hoje de manhã encontrei o seguinte: 3.447,30 - 3.446,01 = 1.28. Fiz um novo ajuste na função, usei um número parecido com o episolon (10**(-7) ou 10**(-16)), só que o meu é um pouco maior. function aint($valor) { return intval($valor*100 + 0.0001)/100; } e a fórmula que usei no formulário ficou assim: <?=dec(abs(aint(aint($p->valor) - aint($p->fim))))?> Hoje deu certo. Espero que ele funcione amanhã, também.
-
Eu tinha um formulário assim <select onchange="location.replace(`vendaInicio(${this.value})`)" name=detalhe class="bg-transparent"> <?php foreach($grupos as $grupo): ?> <option value="<?=date('d/m/y',strtotime($grupo->ddia))?>" <?php if($detalhe==$grupo->ddia) echo "selected"; ?>> <?=date('d/m/y',strtotime($grupo->ddia))?> -> <?=dec($grupo->ttotal)?> </option> <?php endforeach;?> </select> Mas ele só funcionava uma única vez, ele criava uma solicitação tipo vendaInicio(18/02/25), mas quando selecionava outra data, a solicitação saia assim vendaInicio(18/02/vendaInicio(15/02/25). Eu não entendi porque esse problema aconteceu. Pode ser que a culpa não seja do JavaScript, mas sim do meu roteador: arquivo index.php <?php require('config.php'); $requestUri = $_SERVER['REQUEST_URI']; $path = substr($requestUri, strlen($basePath)); if ($path == "") { $path = "loginLogin"; } if (!strpos($path, '(')) { $path .= '()'; } if (preg_match('/^([a-z]+)([A-Z][a-zA-Z]*)\((.*)\)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; $argumentos = explode(',', $matches[3]); $argumentos = array_map('urldecode', $argumentos); if (!empty($argumentos[0]) && !empty($argumentos)) { $classe::$metodo(...$argumentos); } else { $classe::$metodo(); } } else { echo "Formato de URL inválido."; } ?> Mas, eu não fui capaz de resolver o problema. Ao invés disso, mudei a função Venda::inicio($argumento) para Venda::inicio( ), e coloquei a caixa de seleção dentro de um <form>, e tudo funciona como eu espero. Até agora eu não vi nenhum problema em usar a classe estática ao invés da instância da classe, esse é o primeiro caso que enfrentei esse tipo de problema.
-
Tentei copiar o código Laravel para o formulário de login no PHP, e não deu certo. Imaginei que a diferença entre o Laravel e o PHP fosse a tecnologia Vite, então instalei o Tailwind no notebook, e também não deu certo. Então decidi usar o famoso método da tentativa e erro, e fazer com que o login do PHP fosse mais ou menos parecido com o do Laravel, usando o CDN do Tailwind (o JavaScript reclama que ele não deve ser usado no modo produção, mas é uma das poucas coisas que funciona), e eu consegui: arquivo loginView.php <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://cdn.tailwindcss.com"></script> <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100"> <h1 class=text-xl>Projeto Chirper</h1> <main class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg"> <form method="post" action=loginMenu> <div> <label for="email" class=block>Email</label> <input class="w-full p-2 border border-gray-300 rounded-lg focus:outline-blue-700" id="email" type="email" name="email" required="required" autofocus="autofocus" autocomplete="username"> </div> <div class="mt-4"> <label for="password" class=block>Senha</label> <input class="w-full p-2 border border-gray-300 rounded-lg focus:outline-blue-700" id="password" type="password" name="password" required="required" autocomplete="current-password"> </div> <div class="flex items-center justify-end mt-4"> <button class="inline-flex items-center px-4 py-2 bg-gray-500 rounded-md font-semibold text-xs text-white uppercase"> Entrar </button> </div> </form> </main> </div>
-
A minha tela de login no projeto php é um horror na tela do celular, ele só aparece a metade do formulário no modo retrato. Tentei estudar o Laravel para ver como ele consegue colocar todo o formulário do login tanto no modo retrato como no modo paisagem no celular, mas eu não consegui apurar aonde começa o código e onde termina. Pedi ajuda para o Copilot, e ele me arranjou dois arquivos, o HTML e o CSS. Peguei o terminal do VS Code e digitei php -S 0.0.0.0:8000 e no celular eu digitei 192.168.0.4:8000, e comecei a estudar a tal da responsividade. O arquivo CSS é enorme, mas fiquei imaginando como ficaria o celular sem o CSS. O celular continuou funcionando, e diminui todo o HTML nos seguintes códigos: <form> <h2>Login</h2> <div> <input type="text" id="username" name="username" required placeholder="Usuário"> </div> <div> <input type="password" id="password" name="password" required placeholder="Senha"> </div> <input type="submit"> </form> Ou seja, o HTML é responsivo. O CSS é pura perfumaria.
-
Na imagem abaixo eu encontrei uma pequena diferença de R$ 0,01, ele é resultado da equação: C = aint(B - A). Para tentar resolver esse problema, eu improvisei assim: C = aint(B) - aint(A). Ele resolveu o meu problema agora. Não sei se dá para usar essa solução por toda a vida. a função aint que eu criei é essa: <?php function aint($valor) { return intval($valor*100)/100; }
-
Ao invés de conectar o Excel no MySQL remoto, eu pensei em jogar no PHP o serviço do Excel. Criei uma tabela chamada previsão, criei uma classe previsão e também uma imagem previsão. Se eu conseguir terminar o serviço, vou poder fazer as tarefas no celular, não vou mais depender do laptop: arquivo previsao.php <?php class previsao { static function alterar() { $previsao=deca($_POST['previsao']); $conta=$_POST['conta']; bd::x("update tbprevisao set valor=:valor where conta=:conta", ['valor'=>$previsao,'conta'=>$conta])->getx(); return self::inicio(); } static function inicio() { balancete::tbw(1); $painel=bd::x("select * from tbprevisao join tbw on tbprevisao.conta = tbw.conta")->get(); return view('previsaoView',['painel'=>$painel]); } } <?php require('menuView.php'); ?> <script>btMenu.innerHTML="Previsão";document.title="Previsão"</script> <div class="flex"> <div class="w-[50px] text-right">Conta</div> <div class="w-[200px] px-2">Descricao</div> <div class="w-[100px] text-right">Previsão</div> <div class="w-[100px] text-right">Contábil</div> <div class="w-[100px] text-right">Divergência</div> </div> <div class=flex> <?php foreach($painel as $p): ?> <div class="w-[50px] text-right"><?=$p->conta?></div> <div class="w-[200px] px-2 truncate"><?=$p->descricao?></div> <div class="w-[100px] text-right"> <form action=previsaoAlterar method=post> <input class="w-[100px] text-right" name=previsao value=<?=dec($p->valor)?>> <input type=hidden name=conta value=<?=$p->conta?>> </fom> </div> <div class="w-[100px] text-right"><?=dec($p->fim)?></div> <div class="w-[100px] text-right"><?=dec(abs($p->valor - $p->fim))?></div> <?php endforeach;?> </div>
-
O PHP foi a melhor maneira que eu encontrei para conectar o meu celular com o MySQL. Tanto o PHP como o MySQL estão hospedados na Hostinger. O problema é que o meu conhecimento em PHP é muito precário, ainda não posso jogar fora o programa Excel. Assim, todo ano preciso pagar R$ 459,00 para a Microsoft para eu poder usar o Excel (a assinatura se extende ao Access, ao Word, e muitos programas que não uso). Desde 2022, quando aluguei um espaço na Hostinger, preciso fazer um monte de backup do MySQL para eu poder conectar o Excel no banco de dados. Isso é uma chatice para quem detesta trabalhar, como é o meu caso. Assim, hoje eu pedi ajuda ao Copilot, ele me deixou feliz na hora que ele disse que posso conectar o Excel diretamente no MySQL lá na Hostinger. A minha alegria durou pouco tempo, eu não consegui conectar o meu ODBC à Hostinger. O problema não é só o Windows, é também a Hostinger, eu preciso mexer os pausinhos para o Excel poder consultar o banco de dados, conforme esse tutorial: https://www.hostinger.com/tutorials/mysql/how-to-grant-remote-access-mysql-vps Eu ainda não testei o tutorial, e assim continuo fazendo esse serviço chato do backup. Mas quem está na mesma situação que eu, desejo sorte com o tutorial.
-
Selecionar intervalo entre 2 textos no Word.
pergunta respondeu ao Henrique Sanches de Frank K Hosaka em Microsoft Office
[Copilot] Sub FormatTextInRed() Dim doc As Document Dim rng As Range Dim startPos As Long Dim endPos As Long ' Define the text delimiters Dim startText As String Dim endText As String startText = "aluno1" endText = "aluno2" ' Set the document Set doc = ActiveDocument ' Find the start position Set rng = doc.Content With rng.Find .Text = startText .Forward = True .Wrap = wdFindStop .Execute End With startPos = rng.Start + Len(startText) ' Find the end position Set rng = doc.Content With rng.Find .Text = endText .Forward = True .Wrap = wdFindStop .Execute End With endPos = rng.Start ' Format the text between the start and end positions Set rng = doc.Range(startPos, endPos) rng.Font.Color = wdColorRed End Sub -
O MS Access é bacana, eu apanhei durante 20 anos, e até hoje eu continuo apanhando. Pelo que vi, o problema é que existe uma tabela (tbSocio) com os campos (id,nome) e com os seguintes valores (1,Frank),(2,João),(3,Maria),(4,José),(5,Joaquim),(6,João). Também tem um formulário com o nome de frmSocio, e lá dentro tem um botão de navegação com o desenho do próximo registro (btProximo), e duas caixas de texto (txt_id) e (txt_nome). O problema é bem difícil de resolver: como colocar os registros do tbSocio no frmSocio. O primeiro registro deverá ser executado pelo formulário. Os demais registros devem ser executados pelo botão, assim: Option Compare Database Dim rs As DAO.Recordset Private Sub Form_Load() Set rs = CurrentDb.OpenRecordset("SELECT id, nome FROM tbsocios") If Not rs.EOF Then rs.MoveFirst txt_id.Value = rs.Fields("id").Value txt_nome.Value = rs.Fields("nome").Value End If End Sub Private Sub btProximo_Click() If Not rs.EOF Then rs.MoveNext If Not rs.EOF Then txt_id.Value = rs.Fields("id").Value txt_nome.Value = rs.Fields("nome").Value Else MsgBox "Você chegou ao último registro." rs.MovePrevious ' Volta ao último registro válido End If End If End Sub
-
Eu inventei a rotina da baixa de estoque em 1999, quando trabalhava com MS Access, e adaptei em 2020 no PHP, mas ele é lento demais. A rotina olha toda a tabela de produtos, estuda cada caso, para ver se é necessário fazer ajuste para calcular o estoque presumido. Eu queria simplificar, ao invés de olhar tudo, o melhor é olhar o que precisa. Ou seja, na tabela histórico do produto, eu tenho algo do tipo (666,'2025-02-01',1,10.00), (666,'2025-02-02',1,10.00),(666,'2025-02-03',1,10.00), como eu faço para pegar o último registro? Eu achei a solução lá em 1999, mas ele é péssimo para os padrões de 2025. O lado bom de viver em 2025 é que tem o Copilot, é um serviço de inteligência artificial que a Microsoft não cobra nada. Por enquanto. E hoje, o Copilot me apresentou o WITH, eu nem sabia que isso existia no MySQL: <?php $pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); $sql="WITH Produtos AS ( SELECT tbprod.codprod, prod, id, qt, custototal, ROW_NUMBER() OVER (PARTITION BY tbprod.codprod ORDER BY id DESC) AS rn FROM tbprod JOIN tbhistprod ON tbhistprod.codprod = tbprod.codprod WHERE loc <> 'a24' AND qt > 0 AND lcto <> 15092 and lcto <> 15093 AND dia BETWEEN '2025-02-01' AND '2025-02-28') SELECT codprod,prod,id, qt, custototal FROM Produtos WHERE rn = 1"; $produtos=$pdo->query($sql)->fetchAll(PDO::FETCH_OBJ); echo "<table><th>CodProd<th>Prod<th>Qtotal<th>vTotal<th>Uqt<th>Uvalor<th>AjusteQ<th>AjusteV"; foreach($produtos as $produto) { $previa=$pdo->query("select sum(qt) as qt, sum(custototal) as total from tbhistprod where codprod=$produto->codprod")->fetchAll(PDO::FETCH_OBJ)[0]; if($produto->qt!==$previa->qt) { $ajusteQ=$produto->qt - $previa->qt; $ajusteV=$produto->custototal - $previa->total; echo "<tr><td>$produto->codprod<td>$produto->prod <td>$previa->qt<td>$previa->total<td>$produto->qt<td>$produto->custototal <td>$ajusteQ<td>$ajusteV"; } } echo "</table>";
-
O grande problema do Excel com macro é que ele só funciona no PC. Busquei uma alternativa na planilho do Google, eu e o Copilot perdemos o dia todo tentando fazer a planilha consultar o arquivo tbprod.csv, mas no final eu pedi para o Copilot copiar todo o arquivo na página2 da planilha ativa, e usar a página1 do mesmo jeito que no Excel: Apps Script function copiarConteudoCSVParaPlanilha() { var idArquivoCSV = '1wwN8Z-SR0t0pFhrQOyx9YFYpgSiwaQo_'; // Substitua pelo ID do seu arquivo tbprod.csv try { var arquivo = DriveApp.getFileById(idArquivoCSV); var conteudo = arquivo.getBlob().getDataAsString(); var linhas = Utilities.parseCsv(conteudo); var planilha = SpreadsheetApp.getActiveSpreadsheet(); var folha = planilha.getActiveSheet(); // Limpar qualquer conteúdo existente na planilha folha.clear(); // Copiar o conteúdo do CSV para a planilha folha.getRange(1, 1, linhas.length, linhas[0].length).setValues(linhas); SpreadsheetApp.getUi().alert('Conteúdo do arquivo CSV copiado para a planilha com sucesso!'); } catch (erro) { Logger.log('Erro: ' + erro); SpreadsheetApp.getUi().alert('Ocorreu um erro: ' + erro); } } function onEdit(e) { var folhaAtiva = e.source.getActiveSheet(); var celulaEditada = e.range; var valorCelula = celulaEditada.getValue(); if (folhaAtiva.getSheetName() == 'Página1') { var planilha = SpreadsheetApp.getActiveSpreadsheet(); var folhaBusca = planilha.getSheetByName('Página2'); if (!folhaBusca) { SpreadsheetApp.getUi().alert('A planilha "Página2" não foi encontrada.'); return; } var intervaloBusca = folhaBusca.getRange('A:D').getValues(); for (var i = 0; i < intervaloBusca.length; i++) { if (intervaloBusca[i][0] == valorCelula) { var valorCorrespondente = intervaloBusca[i][3]; // Valor da coluna D // Colocar o valor da coluna D ao lado do valor digitado na Página1 celulaEditada.offset(0, 1).setValue(valorCorrespondente); // Opcional: Exibir um alerta com o valor digitado e o valor correspondente SpreadsheetApp.getUi().alert('O valor digitado é: ' + valorCelula + '. O valor correspondente é: ' + valorCorrespondente); return; } } // Se nenhum valor correspondente for encontrado SpreadsheetApp.getUi().alert('Nenhum valor correspondente encontrado para: ' + valorCelula); } }