20. december 2005 - 16:42Der er
18 kommentarer og 2 løsninger
Makro til at slå værdi op og kopiere
Så er jeg her igen med et makro spørgsmål. Jeg troede ellers jeg kunne knække denne selv, men det vil ikke virke... Jeg har brug for en makro, som jeg gætter på skal indsættes i kildekoden for arket. Simpelt forklaret skal makroen gøre følgende:
Kolonne A og B ser f.eks. således ud: 1 Rød 2 Blå 3 Gul
Når jeg nu ændre værdien i kolonne C1 til 2, skal makroen søge i kolonne A, finde rækken med 2, kopiere værdien i den tilsvarende række i kolonne B (Blå) og paste denne ind i D1 - altså samme række, kolonne til højre for det felt jeg indtaster i. Taster jeg i C5, skal værdien altså indsættes i D5. Var det mon til at forstå?
Hos Computerworld it-jobbank er vi stolte af at fortsætte det gode partnerskab med folkene bag IT-DAY – efter vores mening Danmarks bedste karrieremesse for unge og erfarne it-kandidater.
Tak for den fine karma! Det med at forstå spørgsmålene hænger jo i høj grad sammen med selve formuleringen af spørgsmålet, så det er jo i vid udstrækning din egen "skyld". Har før oplevet at nogen brugere forstår jeg fint, mens jeg har svært ved andre. Du hører jo så heldigvis til i den første kategori :0)
Undskyld, det er min fejl vedr. fejl placering af spørgsmålet. Det ER Excel jeg tænker på.
Dit forslag til formel kunne jeg godt lave. Har faktisk en næsten tilsvarende i min D-kolonne allerede. Grunden til at jeg ville prøve at lave det om til en fælles makro, der gælder for hele området D3:D53 er, at brugerne også skal have muligheden for at overskrive den automatisk indsatte værdi i D-feltet. Det kan de godt i dag, men derved overskriver de jo formlen, som evt. skulle bruges igen næste gang de ændrer i kolonne c-feltet. Jeg har altså brug for en funktion der så at sige ligger bagved felterne og giver en default værdi, som man så efterfølgende kan vælge at ændre, uden at fjerne funktionen for fremtidige ændringer.
Prøv at indsætte den her i arkets modul (højreklik på faneblad og vælg "Vis programkode"):
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Not Intersect(Target, Range("C1:C100")) Is Nothing Then Row = Application.WorksheetFunction.Match(Target.Value, [A1:A100], 0) Range("D" & Target.Row) = Range("B" & Row) End If
Hmm, virker delvist. Det er vist mit spørgsmål, der er lidt utydeligt. Når jeg f.eks. skriver 5 i et felt i kolonne C, indsættes værdien af B5 i tilsvarende felt i kolonne D. Det jeg søgte var en funktion, der finder ud af, hvilken række i kolonne A, der har værdien "5". Derefter skal den kopiere værdien af denne række i kolonne B og indsætte i kolonne D.
Jeg kan supplere med, at den oprindelige formel, som gør jobbet, men som altså desværre bliver overskrevet, når man ændrer værdien i feltet eksempelvis ser således ud i felt D7:
Hov, se bort fra den nederst formel. Det er de kolonner jeg benytter i virkeligheden, men vi må heller her for oversigtens skyld holde os til A,B,C og D. Jeg kom bare til at kopiere to gange...
Jeg har fiflet lidt videre med den kode du gav mig og kombineret med andre, jeg tidligere har fået her. Det foregår lidt i blinde, da jeg intet ved om VBA. Så jeg er helt stolt over, at jeg nu har en funktion, der NÆSTEN fungerer som den skal. Der er bare to små problemer tilbage. Kan du løse dem, skal du få dine point.
Det ene er, at når jeg skriver "1", slår den værdien "10" op i stedet for. Alle andre værdier finder den korrekt. Hvorfor mon?
Det andet problem er, at jeg får fejlmeddelelse, hvis jeg forsøger at slette den indtastede værdi i kolonne C. I det tilfælde skulle systemet bare vælge også at slette den tilsvarende værdi i kolonne D. Den kode jeg nu har, og som stort set virker, ser således ud:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim v As Variant Dim c As Range Dim lRow As Long With Range("A5:A83") v = Target Set c = .Find(v, LookIn:=xlValues) If Not c Is Nothing Then lRow = c.Row If Not Intersect(Target, Range("C5:C54")) Is Nothing Then Row = Application.WorksheetFunction.Match(Target.Value, [A5:A83], 0) Range("D" & Target.Row) = Range("B" & c.Row) End If End If End With End Sub
Jeg har stort set løst problemet med at slette. Blot står den og blinker et par sekunder, som om den løber gennem en lang løkke? Jeg er ikke klar over, om der er noget forkert i min opsætning eller jeg bare skal leve med det? Koden ser nu således ud:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim v As Variant Dim c As Range Dim lRow As Long With Range("A5:A83") v = Target If v = "" Then Range("D" & Target.Row) = "" Else Set c = .Find(v, LookIn:=xlValues) If Not c Is Nothing Then lRow = c.Row If Not Intersect(Target, Range("C5:C54")) Is Nothing Then Row = Application.WorksheetFunction.Match(Target.Value, [A5:A83], 0) Range("D" & Target.Row) = Range("B" & c.Row)
Mht det at den står og blinker nogle sekunder, hvis jeg sletter, så sker det samme, hvis jeg taster en værdi fra kolonne A, hvis tilsvarende B-felt er blankt. Det er altså noget, som sker, hvis den værdi, der skal indsættes i kolonne D er blank.
Jeg forstår det ikke. Jeg synes at den funktion jeg forslog 21/12-2005 12:27:23 fungerer som du beskriver.
F.eks. - skriv et tal i f.eks. C5 - funktionen søger efter tallet fra C5 i kolonne A (f.eks. A12) - funktionen tager herefter værdien B12 og skriver den i D5
Ja, det lyder som om du beskriver funktionaliteten rigtigt. Men det var bare ikke sådan den virkede. I stedet for at finde den række, som har værdien 12 i kolonne A, fandt den i stedet bare række 12, og tog værdien af kolonne B. Men det er heller ikke længere problemet. Den kan godt slå værdien op med den udvidede kode jeg beskriver ovenfor. Mit problem nu er primært det med, at den ikke kan slå værdien "1" op, hvis jeg skriver den i kolonne C. Den finder konsekvent værdien "10" i stedet for. Og så om du har et bud på, hvorfor den tager forholdsvis lang tid om at indsætte en blank værdi.
Hmm, ja det var åbenbart problemet??? Det er underligt, for det er netop i A5, at værdien "1" findes. Men nu har jeg sat den til at begynde søgningen i A4 (som er blankt), og så kan den godt finde værdien "1" i A5 og returnere den tilsvarende værdi fra B5 til aktuelle felt i kolonne D. Mystisk... Nå, men skidt med at jeg ikke forstår det. Nu virker det i hvert fald. Så er der bare den lidt irriterende ventetid når jeg sletter og den ligesom løber igennem alle beregninger i skemaet og opdaterer - eller hvad det er den gør. Men det kan man leve med.
jeg forsøgte i øvrigt at indsætte en Else-sætning i koden, hvor jeg ville have den til at bringe en advarsel, hvis man brugte en værdi, som ikke findes i kolonne A.
Koden tror jeg ser således ud:
Else MsgBox "Der findes ingen kategori, der svarer til dette nummer. Vælg et andet!"
og jeg forsøgte at sætte den ind forskellige steder i koden. Men enten virker den slet ikke, eller også virker den hver gang jeg taster. Hvis du er frisk på et bud på, hvor jeg skal sætte den ind så den fremkommer når funtionen .Find ikke kunne finde en værdi svarende til v, så vil jeg være glad. Men du har jo klaret den oprindelige opgave, så jeg giver pointene nu. Tak for hjælpen.
Problemt med ingen matchende værdi skyldes at der opstår en fejl, og derfor afbrydes programafviklingen. Så det må kunne klares med at styre hvad der sker, når der opstår en fejl. Det kan f.eks. gøres således:
Private Sub Worksheet_Change(ByVal Target As Excel.Range) Dim v As Variant Dim c As Range Dim lRow As Long
On Error GoTo Fejlhåndtering
With Range("A4:A83") v = Target If v = "" Then Range("D" & Target.Row) = "" Else Set c = .Find(v, LookIn:=xlValues) If Not c Is Nothing Then lRow = c.Row If Not Intersect(Target, Range("C5:C54")) Is Nothing Then Row = Application.WorksheetFunction.Match(Target.Value, [A4:A83], 0) Range("D" & Target.Row) = Range("B" & c.Row) End If End If End If End With
Exit Sub Fejlhåndtering: MsgBox "Der findes ingen kategori, der svarer til dette nummer. Vælg et andet!"
Nu skulle det være lidt bedre. Jeg har trimmet koden lidt, så det overflødige er fjernet. Det betyder bl.a. at den nu også kan finde værdier, der står i det første felt. Desuden er FIND ændret så den søger på hele tal (dvs. den returnerer ikke 24 hvis du søger på 2). Så blev der lige luget lidt ud i overflødige if-sætninger og variable.
Private Sub Worksheet_Change(ByVal Target As Excel.Range) Dim c As Range
If Not Intersect(Target, Range("C5:C54")) Is Nothing Then With Range("A5:A83") If Target = "" Then Range("D" & Target.Row) = "" Else Set c = .Find(Target, LookIn:=xlValues, LookAt:=xlWhole) If Not c Is Nothing Then Range("D" & Target.Row) = Range("B" & c.Row) Else MsgBox "Der findes ingen kategori, der svarer til dette nummer. Vælg et andet!" Range("D" & Target.Row) = "" End If End If End With End If
Dette sidste var genialt. Det fungerer helt fuldstændig perfekt. Ingen lange løkker man skal vente på. Alle tal kan findes, og fejl-advarslen kommer frem når den skal og eller ikke. Tusind tak! Du har snildt fortjent dine point! Glædelig jul. Lars Mollerup-Degn
Tak - julen var glædelig! Og godt nytår til dig :0)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.