petek, 29. julij 2011

Tweetdeck v Ubuntuju

Navkljub temu, da dandanes uporabnik računalnikov ločimo na jabolkarje in oknarje, se občasno še najdejo ljudje, ki uporabljajo operacijske sisteme temelječe na Linux. In taki s(m)o velikokrat prikrajšani za programe, ki jih v drugih OS z lahkoto namestimo. Kljub strahu, da bo v Ubuntu-ju vse strašno zakomplicirano in neizvedljivo, je nameščanje twitter aplikacije Tweetdeck popolnoma enostavno in zahteva od uporabnika le malce tipkanja oz. prepisovanja.

    Program Tweetdeck uporablja izvajalno okolje (runtime) AdobeAIR, ki ga najdemo na naslovu:

      http://get.adobe.com/air/

      Izberemo datoteko s končnico .bin in jo prenesemo na lokalni računalnik.
      Ko je datoteka (AdobeAIRInstaller.bin) prenešena, kliknemo nanjo z desno miškino tipko, izberemo zavihek "Dovoljenja" in obkljukamo "Dovoli izvajanje datoteke kot programa".

      Sledi "najzahtevnjši" korak, ki poleg uporabe miške, zahteva še uporabo tipkovnice. Odpremo "Terminal" in se premaknemo v mapo, kamor smo shranil datoteko "AdobeAIRInstaller.bin" in vnesemo naslednja ukaza:

       chmod +x AdobeAIRInstaller.bin

       sudo ./AdobeAIRInstaller.bin

      S tem smo namestili izvajalno okolje AdobeAir.

      Sedaj se moramo samo še odpraviti na spletni naslov http://tweetdeck.com in prenesti zadnjo različico programa Tweetdeck.

      No, malo klikanja je še potrebno, ampak več kot "OK" menda res ne.

      torek, 5. julij 2011

      Funkcije LEN, LEFT in DATEDIF

      Lep deževni pozdrav, slučajnemu mimoidočemu. Uspelo mi je sestavit še eno objavo, pa čeprav sem v teh toplih dneh veliko raje na kolesu po Katarini in okolici, kot pa pred "kišto". No, služba je služba in služba je denar, zato moramo tudi delat. In med delom sem se spomnil, še dveh pametnih zadev.

      1. LEFT & LEN
      Pa gremo lepo po vrsti. Prva težava, če ji lahko tako rečemo, je bila, ko sem sem moral sešteti porabo prenosa podatkov na mobilnem telefonu. Podatki so zapisani v, za Excel, neuporabni obliki; npr. 180,0MB. Lahko bi sicer preprosto uporabil Ctrl+H (najdi in zamenjaj), ter vse MB zamenjal s praznim besedilom. Toda to nebi bilo tako zanimivo, zato sem raje uporabil funkcijo LEN() in LEFT(). Postopek gre pa nekako tako:
      v prvem stolpcu so podatki napisani v zgoraj omenjeni obliki. Decimalna vejica je uporabljena samo ko je decimalka različna od 0. Vedno pa velja, da sta zadnja dva znaka MB. Formula se torej glasi:

      =LEFT(A2;LEN(A2)-2)

      torej najprej preberemo število znakov v nizu z LEN(A2), odštejemo 2 znaka (MB) in nazadnje preberemo LEN()-2 znaka, šteto z leve strani.


      Če nam dobljenega rezultata še vedno noče seštevati, ga označimo, kopiramo in uporabimo ukaz: "Pretvori v število".

      2. DATEDIF
      Datedif je uporaben predvsem v kadrovski službi in prav od tam je prišlo vprašanje če Excel zna in kako bi se naredilo, da bi iz datuma rojstva določenega zaposlenega izpisalo starost na današnji dan. Rešitev je pravzaprav zelo preprosta, uporabimo funkcijo DATEDIF, malo &, malo "" in to je to.

      DATEDIF je dejansko sestavljena tako:
      =DATEDIF(Datum1, Datum2, Interval)

      V našem primeru jo uporabimo za razliko med danes NOW() in rojstnim datumom. Y, YM in MD uporabimo za leta, mesece in dneve.

      Torej v celico D2 smo vnesli rojstni datum 25.6.1991 (Dan državnosti) v celico E2
      =DATEDIF(D2;NOW(); "Y") & " let, " & DATEDIF(D2;NOW(); "YM") & " mesecev in " & DATEDIF(D2;NOW(); "MD") & " dni."

      in na današnji dan je rezultat: 20 let, 0 mesecev in 10 dni.

      torek, 28. junij 2011

      VBA in SQL drugi del

      Takole, od zadnjič sem celo vso stvar malce nadgradil in sedaj lahko z veseljem povem, da deluje iskanje kot se spodobi. Poleg tega, sem dodal kopiranje podatkov v nov excelov dokument, brisanje rezultatov,... Malce pa sem dodelal tudi sam obrazec za iskanje in sedaj izgleda tako:



      Iskalno okno se avtomatsko zažene ob zagonu Excelove datoteke. To storimo z ukazom:


      Private Sub Workbook_Open()
          UserForm1.Show
      End Sub

      Ukaz vnesemo tako, da v VBA-ju dvakrat kliknemo ThisWorkBook v VBAProject in potem iz padnih menijev izberemo: Workbook in Open.

      Ostalo kodo vnesemo v obrazec. Izgleda pa tako:


      Private Sub CmdIsci_Click()


      'spuca vse podatke na listu
      List1.Cells.Clear


          With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
              "ODBC;DATABASE=zzzzz;DRIVER={MySQL ODBC 3.51 Driver};OPTION=0;;PORT=0;SERVER=xxx.xxx.x.xx;UID=XXX;PASSWORD=YYY" _
              , Destination:=Range("$A$1")).QueryTable
              .CommandText = Array( _
                      "SELECT inkasso_2010_om_odvpr_0.OM, inkasso_2010_om_odvpr_0.OM_NAZIV AS 'NAZIV', inkasso_2010_obcine_odvpr_0.OBCINA_NAZIV AS 'OBČINA', inkasso_2010_sif_kraj_sk_odvpr_0.KRAJ_SK_NAZIV AS 'NASELJE', inkas" _
              , _
              "so_2010_sif_ulic_odvpr_0.ULICA_NAZIV AS 'ULICA', CONCAT(inkasso_2010_om_odvpr_0.OM_HS,inkasso_2010_om_odvpr_0.OM_HSD) AS 'Hst', inkasso_2010_om_posode_odvpr_0.POSODE_ODPADEK AS 'FRAKCIJA', inkasso_201" _
              , _
              "0_posode_odvpr_0.POSODA_VOLUMEN AS 'VOL', inkasso_2010_om_posode_odvpr_0.POSODE_FREKVENCA AS 'FREK', inkasso_2010_om_posode_odvpr_0.POSODE_IDENTST AS 'INVENTARNA', inkasso_2010_om_pogodbe_odvpr_0.POGO" _
              , _
              "DBA_STEVILKA AS 'POGODBA'" & Chr(13) & "" & Chr(10) & "FROM sezana.inkasso_2010_obcine_odvpr inkasso_2010_obcine_odvpr_0, sezana.inkasso_2010_om_odvpr inkasso_2010_om_odvpr_0, sezana.inkasso_2010_om_pogodbe_odvpr inkasso_2010_om" _
              , _
              "_pogodbe_odvpr_0, sezana.inkasso_2010_om_posode_odvpr inkasso_2010_om_posode_odvpr_0, sezana.inkasso_2010_posode_odvpr inkasso_2010_posode_odvpr_0, sezana.inkasso_2010_sif_kraj_sk_odvpr inkasso_2010_s" _
              , _
              "if_kraj_sk_odvpr_0, sezana.inkasso_2010_sif_ulic_odvpr inkasso_2010_sif_ulic_odvpr_0" & Chr(13) & "" & Chr(10) & "WHERE inkasso_2010_om_odvpr_0.OM = inkasso_2010_om_posode_odvpr_0.OM AND inkasso_2010_om_odvpr_0.KRAJ_SK_SIFRA = i" _
              , _
              "nkasso_2010_sif_kraj_sk_odvpr_0.KRAJ_SK_SIFRA AND inkasso_2010_om_odvpr_0.ULICA_SIFRA = inkasso_2010_sif_ulic_odvpr_0.ULICA_SIFRA AND inkasso_2010_om_odvpr_0.OM = inkasso_2010_om_pogodbe_odvpr_0.OM AN" _
              , _
              "D inkasso_2010_om_odvpr_0.OBCINA_SIFRA = inkasso_2010_obcine_odvpr_0.OBCINA_SIFRA AND inkasso_2010_om_pogodbe_odvpr_0.POGODBA_STEVILKA = inkasso_2010_om_posode_odvpr_0.POGODBA_STEVILKA AND inkasso_201" _
              , _
              "0_om_posode_odvpr_0.POSODA_SIFRA = inkasso_2010_posode_odvpr_0.POSODA_SIFRA AND ((inkasso_2010_om_pogodbe_odvpr_0.POGODBA_AKTIVNA='T') AND (inkasso_2010_om_posode_odvpr_0.POSODE_ZARACUNLJIVOST=2) AND " _
              , "(inkasso_2010_om_odvpr_0.OM_AKTIVEN='T'))" _
              , _
              " AND inkasso_2010_om_odvpr_0.OM LIKE '%" & UserForm1.TxtOm.Text & "%' AND inkasso_2010_om_odvpr_0.OM_NAZIV LIKE '%" & UserForm1.TxtNaziv.Text & "%' AND inkasso_2010_obcine_odvpr_0.OBCINA_NAZIV LIKE '%" & UserForm1.TxtObcina.Text & "%'", _
              " AND inkasso_2010_sif_kraj_sk_odvpr_0.KRAJ_SK_NAZIV LIKE '%" & UserForm1.TxtNaselje.Text & "%' AND inkasso_2010_sif_ulic_odvpr_0.ULICA_NAZIV LIKE '%" & UserForm1.TxtUlica.Text & "%' AND inkasso_2010_om_odvpr_0.OM_HS LIKE '%" & UserForm1.TxtHisna.Text & "%'", _
              " AND inkasso_2010_om_odvpr_0.OM_HSD LIKE '%" & UserForm1.TxtDod.Text & "%' AND inkasso_2010_om_posode_odvpr_0.POSODE_ODPADEK LIKE '%" & UserForm1.TxtFrakcija.Text & "%' AND inkasso_2010_om_posode_odvpr_0.POSODE_IDENTST LIKE '%" & UserForm1.TxtInventarna.Text & "%' AND inkasso_2010_om_posode_odvpr_0.POGODBA_STEVILKA LIKE '%" & UserForm1.txtPogodba.Text & "%'" _
              )
              .RowNumbers = False
              .FillAdjacentFormulas = False
              .PreserveFormatting = True
              .RefreshOnFileOpen = False
              .BackgroundQuery = True
              .RefreshStyle = xlInsertDeleteCells
              .SavePassword = False
              .SaveData = True
              .AdjustColumnWidth = True
              .RefreshPeriod = 0
              .PreserveColumnInfo = True
              .ListObject.DisplayName = "Tabela_izpis"
              .Refresh BackgroundQuery:=False
          End With
      End Sub


      Private Sub cmdKopiraj_Click()
              
          ActiveWorkbook.Sheets(1).Activate
          Range("A1:J1, Tabela_izpis").Select
          Selection.Copy
              
          Workbooks.Add
          ActiveWorkbook.Sheets(1).Activate
          ActiveSheet.Cells(1, 1).PasteSpecial
        
      End Sub


      Private Sub cmdNovo_Click()
          Workbooks("iskanje_sql.xlsm").Activate
      End Sub


      Private Sub CommandButton1_Click()
          List1.Cells.Clear
      End Sub

      sreda, 15. junij 2011

      VBA in SQL

      Živimo, baje, v času recesije, zato je potrebno včasih kakšno stvar narediti po težji poti. Ena od takih, se mi je zgodila nekaj dni nazaj. Gre sicer za precej banalen primer, ki bi se ga dalo preprosto rešiti s pomočjo MS Accessa ali pa bi se preprosto programerjem plačalo, da naredijo poročilo v trenutne programu. No, ničesar od tega ni bilo, zato sem se držal reka: "pomagaj si sam in bog ti bo pomagal".

      Opis problema

      Program za vodenje katastrov temelji na bazi MySql, vendar nima pripravljenih določenih izpisov. Z uporabo Excela lahko sicer naredimo query, a se pri malo manj ukih uporabnikih zatakne pri nastavljanju parametrov izpisa. Navadno pride do tega, da kliknejo na bližnjico za zagon poizvedbe in potem pobrišejo vse nepotrebne vrstice (mogoče celo stolpce). Tukaj pa nam pride hitro v pomoč VBA.

      Celotna skripta še ni dodelana, ampa za prvo silo deluje. Sestavljena je iz preprostega obrazca s tremi besedilnimi polji (TextBox) in dveh gumbov.

      Nato pa seveda dodamo še malo besedila, ki bo naredilo nekaj pametnega.

      Za gum "Išči" sledi naslednje:


      Private Sub CommandButton1_Click()


      'Spucamo vse podatke na delovnem listu
      List1.Cells.Clear


      'povezemo se z MySQL bazo
      'ce dopisemo ;PASSWORD=xxxxxx;, ne rabimo vpisovat gesla po zagonu skripte
          With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
              "ODBC;DATABASE=komunala;DRIVER={MySQL ODBC 3.51 Driver};OPTION=0;;PORT=0;UID=danijel;" _
              , Destination:=Range("$A$1")).QueryTable
              .CommandText = Array( _
              "SELECT bass_pogodbe_0.ID, bass_pogodbe_0.OBCINA_SIFRA, bass_pogodbe_0.OBCINA_NAZIV, bass_pogodbe_0.KRAJ_SK_SIFRA, bass_pogodbe_0.KRAJ_SK_NAZIV, bass_pogodbe_0.ULICA_SIFRA, bass_pogodbe_0.ULICA_NAZIV, " _
              , _
              "bass_pogodbe_0.OM_HS, bass_pogodbe_0.OM_HSD, bass_pogodbe_0.OM, bass_pogodbe_0.OM_NAZIV, bass_pogodbe_0.OM_PLACNIK, bass_pogodbe_0.NAZIV, bass_pogodbe_0.NASLOV, bass_pogodbe_0.PTT, bass_pogodbe_0.KRAJ" _
              , _
              ", bass_pogodbe_0.POGODBA_STEVILKA" & Chr(13) & "" & Chr(10) & "FROM komunala.bass_pogodbe bass_pogodbe_0" & Chr(13) & "" & Chr(10) & _


      'pa se pogoji, ki se nanasajo na textboxe
              "WHERE (bass_pogodbe_0.ULICA_NAZIV LIKE '%" & UserForm1.txtUlica.Text & "%' AND bass_pogodbe_0.OBCINA_SIFRA LIKE '%" & UserForm1.txtObcina.Text & "%' AND bass_pogodbe_0.OM_NAZIV LIKE '%" & UserForm1.txtOmNaziv.Text & "%' )")
              .RowNumbers = False
              .FillAdjacentFormulas = False
              .PreserveFormatting = True
              .RefreshOnFileOpen = False
              .BackgroundQuery = True
              .RefreshStyle = xlInsertDeleteCells
              .SavePassword = False
              .SaveData = True
              .AdjustColumnWidth = True
              .RefreshPeriod = 0
              .PreserveColumnInfo = True
              .ListObject.DisplayName = "Tabela_Poizvedba_iz_mysql"
              .Refresh BackgroundQuery:=False
          End With


      End Sub

      Z drugim gumbom natisnemo vsebino lista:


      Private Sub CommandButton2_Click()
           With ActiveSheet.PageSetup
              .PrintTitleRows = "$1:$1"
              .PrintTitleColumns = ""
          End With
      Application.Dialogs(xlDialogPrint).Show
      End Sub



      To je nekako osnovno, kar je bilo narejeno. Po željah in zmožnostih, bomo pa dodajali tudi nove stvari.

      petek, 15. april 2011

      Obrazec za vnos

      Excel je zelo uporaben ko se soočimo z vnosom podatkov. Uporabimo lahko vgrajen obrazec, lahko pa si seveda izdelamo svojega. Vse skupaj je zelo preprosto in velikokrat nam precej olajša delo.

      Kot vedno zaženemo VBA (Alt+F11) in vstavimo obrazec (Insert -> UserForm). Najprej se nam prikaže samo ozadje obrazca, ki ga oblikujemo po želji; vstavimo Tekstovna polja (textbox), gumbe (button), Imena (label),...

      V naslednjem primeru je prikazana izdelava obrazca za vnos podatkov o prometni signalizaciji v določenem naselju.

      Sama oblika obrazca je dokaj preprosta in pregledna, ker se mi ni dalo preveč ukvarjati z lepotičenjem.


      Ko zaključimo z oblikovanjem obrazca, pa je potrebno dodati tudi nekaj programske kode, ki poskrbi, da postane obrazec uporaben. V oknu Project Explorer (na zgornji sliki je to levo zgornje okno) poiščemo naš obrazec (UserForm1), kliknemo nanj z desno tipko in izberemo View Code.

      Vpišemo kodo, ki naj se izvede:

      Private Sub Initialize()
      'ob zagonu pobrišemo vsa polja v obrazcu.
          txtOdsek.Value = ""
          txtOznaka.Value = ""
          txtNaziv.Value = ""
          txtStacionaza = ""
          txtVisina = ""
          txtOpomba = ""
      End Sub

      Private Sub cmdIzhod_Click()
      'gumb za izhod zapre obrazec
          Unload Me
      End Sub

      Private Sub cmdVnos_Click()
      'ko kliknemo na gumb vnos, naj se vsebina obrazca vnese v prvo prazno vrstico
      'na  delovnem listu "podatki"
                
          ActiveWorkbook.Sheets("podatki").Activate

          Range("A1").Select

          Do

          If IsEmpty(ActiveCell) = False Then

              ActiveCell.Offset(1, 0).Select

          End If

          Loop Until IsEmpty(ActiveCell) = True

          ActiveCell.Value = txtOdsek.Value

          ActiveCell.Offset(0, 1) = txtOznaka.Value

          ActiveCell.Offset(0, 2) = txtNaziv.Value

          ActiveCell.Offset(0, 3) = txtStacionaza.Value
        
          ActiveCell.Offset(0, 4) = txtVisina.Value
        
          ActiveCell.Offset(0, 5) = txtOpomba.Value

        
          'Range("A1").Select
          ActiveCell.Offset(1, 0).Select
      End Sub

      In zaženemo s tipko F5 ali pa kliknemo na  Run -> Run Sub/User Form.

      torek, 15. marec 2011

      Povprečje, min, max

      Danes pa nekaj, kar sploh ni bilo narejeno s pomočjo VBA. Gre za kombinacijo uporaba funkcije IF in AVERAGE.

      Težava, ki je iskala rešitev, je bila v tem, da so podatki lahko v 1 ali pa več stolpcev. Ker je maksimalno število stolpcev znano, sem vse skupaj naredil bolj po partizansko; samo da dela.

      Glava poročila je vedno enaka in v celicah D26 do M26 je potrebno izračunat povprečje vrednosti. Ampak. Ne vemo koliko vrstic podatkov, pa tudi vsi stolpci nimajo vedno podatkov (senzor mrtev). Torej vedno preverimo, če je v dotični celici sploh zapisana vrednost, izračunamo povprečje za tisto število celic, ki imajo številske podatke. Če pa podatkov ni, se v poročilni tabeli izpiše "Ni podatkov".

      =IF(N30<>0;AVERAGE(N30:(INDEX(N30:N27201; COUNT(N30:N27201))));"Ni podatkov")

      Vse skupaj je dejansko preprosto kot znana srbska nacionalna jed.

      ponedeljek, 14. marec 2011

      Odpiranje, zapiranje, rangi,...

      Naslov je čuden, pa naj bo še vsebina. Sicer nič posebnega, mi je pa vzelo nekaj uric prijetnega dela.

      Začetna želja je bila, da iz podatkov nekih sond (10 temperaturnih sond), naredimo poročilo, ki vsebuje minimalno, maksimalno in povprečno vrednost odčitka ter seveda nariše graf. Nič posebnega, lahko se naredi tudi "na roke". Toda življenje ni zanimivo, če ne malo kompliciramo.

      V spodnjem nakladanju manjka samo še malo lepote. V izdelku je seveda še datoteka, z logotipom, opisom, gumbom za zagon...

      No, da še malo opišem, kaj sploh je to. Ko zaženemo proceduro, se odpre okno za odpiranje datoteke (s podatki), odpremo datoteko in vpraša nas po območju, ki vsebuje potrebne podatke. Označimo, kliknemo OK in že sledi drugo odpiranje datoteke. Tokrat izberemo datoteko, ki vsebuje vzorec poročila in nekaj malega funkcij (min, max, average, if...malce, nam popravi izgled). V to datoteko se kopirajo podatki, ki smo jih izbrali v prejšnji datoteki. Nato procedura še nariše graf, nas vpraša kam želimo shraniti novo poročilo ter zapre datoteko s podatki in datoteko z vzorčnim poročilom.

      Sub vnos()

      Dim sPorocilo As String
      Dim sPodatki As String
      Dim wbPodatki As Variant


      'odpremo datoteko s podatki

      sPodatki = Application.GetOpenFilename(fileFilter:="Excel FIles (*.xls), *.xls", _
                                              Title:="Prosim izberi datoteko s podatki")
                  If sPodatki = "False" Then Exit Sub
                
      Workbooks.Open Filename:=sPodatki
      wbPodatki = Application.ActiveWorkbook.Name

       
      'V datoteki s podatki iz termometrov izberem obseg podatkov: od ure do zadnjega temperaturnega senzorja 'oz po želji

      Dim rRange As Range

      On Error Resume Next
          Application.DisplayAlerts = False

          Set rRange = Application.InputBox(Prompt:="Prosim izberi obseg vhodnih podatkov", _
          Title:="Določi obseg", Type:=8)

      On Error GoTo 0

          Application.DisplayAlerts = True

          If rRange Is Nothing Then
              Exit Sub

          Else
              'podatke kopiramo
              rRange.Copy

          End If

      'Odpiranje izbrane xls datoteke z vzorcem porocila

      sPorocilo = Application.GetOpenFilename(fileFilter:="Excel Files (*.xls), *.xls", _
                                              Title:="Prosim izberi datoteko z vzorcem poročila")
          If sPorocilo = "False" Then Exit Sub

      Workbooks.Open Filename:=sPorocilo

      'aktiviramo delovni zvezek in nato delovni list ter skočimo v celico C30
      ActiveWorkbook.Sheets("podatki").Activate
      ActiveSheet.Cells(30, 3).Activate

      'prilepimo podatke
      ActiveCell.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
              :=False, Transpose:=False


      'pobrišemo odložišče
      Application.CutCopyMode = False


      'narišemo graf
      Dim povp As Range
      Dim ura As Range
      Dim vrstica As Integer
      Dim vrs As String
      Dim vrsx As String


      ActiveWorkbook.Sheets("podatki").Activate

      vrstica = WorksheetFunction.Count(Range("D30", "D25000")) + 29
      vrs = "N" & vrstica
      vrsx = "O" & vrstica

      Set povp = Range("N30", vrs)
      Set ura = Range("O30", vrsx)

          ActiveWorkbook.Sheets("podatki").Select
          ActiveSheet.Shapes.AddChart.Select
          ActiveChart.ChartType = xlLine
      'seveda bo grafikon poimenovan grafikon in bo na svojem listu
          ActiveChart.Location Where:=xlLocationAsNewSheet, Name:="Grafikon"
          ActiveWorkbook.Charts("Grafikon").Activate
          ActiveChart.SeriesCollection.NewSeries
          ActiveChart.SeriesCollection(2).Name = "='podatki'!$N$29"
          ActiveChart.SeriesCollection(2).Values = povp
          ActiveChart.SeriesCollection(2).XValues = ura
          ActiveChart.SeriesCollection(1).Delete

      'in shranimo datoteko

         fileSaveName = Application.GetSaveAsFilename( _
          fileFilter:="Excel Files (*.xls), *.xls")

          If fileSaveName = False Then
              Exit Sub
          End If

      ' Shrani datoteko v format xls
      ActiveWorkbook.SaveAs Filename:= _
              fileSaveName, FileFormat:=xlExcel8, _
              CreateBackup:=False

      'lepo je, če uporabniku kaj povemo
          file_name_saved = ActiveWorkbook.FullName
          MsgBox "Datototeka je shranjena: " & vbCr & vbCr & file_name_saved

      'zapremo datoteko z vzorčnim poročilom in s podatki
          ActiveWorkbook.Close
          Workbooks(wbPodatki).Close


      End Sub